From commits at source.squeak.org Fri May 1 09:04:47 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 09:04:49 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-tfel.240.mcz Message-ID: Tim Felgentreff uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-tfel.240.mcz ==================== Summary ==================== Name: CollectionsTests-tfel.240 Author: tfel Time: 1 May 2015, 11:04:36.037 am UUID: 74204945-fbd6-6c49-9348-caafa98fb628 Ancestors: CollectionsTests-mt.239 Add a test case to check that ByteString>>findSubstring:in:startingAt:matchTable: behaves the same way as the primitive implementation (esp when using a negative index for startingAt:) =============== Diff against CollectionsTests-mt.239 =============== Item was added: + ----- Method: StringTest>>testFindSubstringInStartingAtMatchTable (in category 'tests - finding') ----- + testFindSubstringInStartingAtMatchTable + + | str tbl cm | + str := 'hello '. + tbl := String classPool at: #CaseSensitiveOrder. + self assert: (str findSubstring: ' ' in: str startingAt: 1 matchTable: tbl) = 6. + self assert: (str findSubstring: 'q' in: str startingAt: 1 matchTable: tbl) = 0. + self assert: (str findSubstring: 'q' in: str startingAt: -1 matchTable: tbl) = 0. + self assert: (str findSubstring: ' ' in: str startingAt: -1 matchTable: tbl) = 6. + + "The next test ensures that the fallback code works just as well" + cm := (CompiledMethod newFrom: (ByteString >> #findSubstring:in:startingAt:matchTable:)). + cm objectAt: 1 put: (cm header bitAnd: 16r1FF bitInvert). + self assert: (cm valueWithReceiver: str arguments: {' '. str. 1. tbl}) = 6. + self assert: (cm valueWithReceiver: str arguments: {'q'. str. 1. tbl}) = 0. + self assert: (cm valueWithReceiver: str arguments: {'q'. str. -1. tbl}) = 0. + self assert: (cm valueWithReceiver: str arguments: {' '. str. -1. tbl}) = 6. + ! From commits at source.squeak.org Fri May 1 09:07:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 09:07:10 2015 Subject: [squeak-dev] The Trunk: Collections-tfel.623.mcz Message-ID: Tim Felgentreff uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-tfel.623.mcz ==================== Summary ==================== Name: Collections-tfel.623 Author: tfel Time: 1 May 2015, 11:06:35.625 am UUID: baf2902d-52b9-2442-a513-8a5a6ff0ce30 Ancestors: Collections-nice.622 fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 =============== Diff against Collections-nice.622 =============== Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! From commits at source.squeak.org Fri May 1 09:51:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 09:51:56 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.953.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.953.mcz ==================== Summary ==================== Name: Morphic-mt.953 Author: mt Time: 1 May 2015, 11:51:15.58 am UUID: 20ca3687-6855-9d48-aa9a-efbc4a201aa4 Ancestors: Morphic-mt.952 Text editor hooks modified to be more descriptive on model side. And to not confuse Tweak. =============== Diff against Morphic-mt.952 =============== Item was changed: ----- Method: TextEditor>>debugIt (in category 'do-its') ----- debugIt | receiver context | self lineSelectAndEmptyCheck: [^self]. + (model respondsTo: #debugExpression:) + ifTrue: [^ model perform: #debugExpression: with: self selection]. - (model respondsTo: #debugIt:) - ifTrue: [^ model perform: #debugIt: with: self selection]. receiver := (model respondsTo: #doItReceiver) ifTrue: [model doItReceiver] ifFalse: [nil]. context := (model respondsTo: #doItContext) ifTrue: [model doItContext] ifFalse: [nil]. (self compileSelectionFor: receiver in: context) ifNotNil: [:method | self debug: method receiver: receiver in: context].! Item was changed: ----- Method: TextEditor>>evaluateSelectionAndDo: (in category 'do-its') ----- evaluateSelectionAndDo: aBlock "Treat the current selection as an expression; evaluate it and invoke aBlock with the result." | result rcvr ctxt | self lineSelectAndEmptyCheck: [^ nil]. + (model respondsTo: #evaluateExpression:) ifTrue: [ + ^ aBlock value: (model perform: #evaluateExpression: with: self selection)]. - (model respondsTo: #evaluate:) ifTrue: [ - ^ aBlock value: (model perform: #evaluate: with: self selection)]. (model respondsTo: #doItReceiver) ifTrue: [ rcvr := model doItReceiver. ctxt := model doItContext] ifFalse: [rcvr := ctxt := nil]. result := [ rcvr class evaluatorClass new evaluate: self selectionAsStream in: ctxt to: rcvr notifying: self ifFail: [morph flash. ^ nil] logged: true. ] on: OutOfScopeNotification do: [ :ex | ex resume: true]. + (model respondsTo: #expressionEvaluated:result:) ifTrue: [ + model perform: #expressionEvaluated:result: with: self selection with: result]. - (model respondsTo: #evaluated:result:) ifTrue: [ - model perform: #evaluated:result: with: self selection with: result]. ^aBlock value: result! From commits at source.squeak.org Fri May 1 09:52:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 09:52:32 2015 Subject: [squeak-dev] The Trunk: MorphicTests-mt.29.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicTests to project The Trunk: http://source.squeak.org/trunk/MorphicTests-mt.29.mcz ==================== Summary ==================== Name: MorphicTests-mt.29 Author: mt Time: 1 May 2015, 11:52:25.528 am UUID: 79cef7f2-a107-194e-b2c0-88452a5711b5 Ancestors: MorphicTests-mt.28 Tests added for text editor's model callbacks. =============== Diff against MorphicTests-mt.28 =============== Item was added: + ValueHolder subclass: #MorphicTestTextModel + instanceVariableNames: 'flags result' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Text Support'! Item was added: + ----- Method: MorphicTestTextModel>>debugExpression: (in category 'do-its general') ----- + debugExpression: anExpression + + self flags add: #expressionDebugged. + self result: (Compiler evaluate: anExpression).! Item was added: + ----- Method: MorphicTestTextModel>>doItContext (in category 'do-its support') ----- + doItContext + + self flags add: #doItContext. + ^ nil! Item was added: + ----- Method: MorphicTestTextModel>>doItReceiver (in category 'do-its support') ----- + doItReceiver + + self flags add: #doItReceiver. + ^ self result! Item was added: + ----- Method: MorphicTestTextModel>>exploreIt:result: (in category 'do-its') ----- + exploreIt: expression result: object + + self flags add: #explored. + self result: object.! Item was added: + ----- Method: MorphicTestTextModel>>expressionEvaluated:result: (in category 'do-its general') ----- + expressionEvaluated: anExpression result: anObject + + self flags add: #expressionEvaluated. + self result: anObject.! Item was added: + ----- Method: MorphicTestTextModel>>flags (in category 'as yet unclassified') ----- + flags + + ^ flags ifNil: [flags := Bag new]! Item was added: + ----- Method: MorphicTestTextModel>>hasFlag: (in category 'as yet unclassified') ----- + hasFlag: aSymbol + + ^ self flags includes: aSymbol! Item was added: + ----- Method: MorphicTestTextModel>>inspectIt:result: (in category 'do-its') ----- + inspectIt: expression result: object + + self flags add: #inspected. + self result: object.! Item was added: + ----- Method: MorphicTestTextModel>>printIt:result: (in category 'do-its') ----- + printIt: expression result: object + + self flags add: #printed. + self result: object printString.! Item was added: + ----- Method: MorphicTestTextModel>>result (in category 'as yet unclassified') ----- + result + + ^ result! Item was added: + ----- Method: MorphicTestTextModel>>result: (in category 'as yet unclassified') ----- + result: anObject + + result := anObject.! Item was added: + MorphicTestTextModel subclass: #MorphicTestTextModelWithEvaluationSupport + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Text Support'! Item was added: + ----- Method: MorphicTestTextModelWithEvaluationSupport>>evaluateExpression: (in category 'do-its general') ----- + evaluateExpression: anExpression + + self flags add: #expressionEvaluated. + self result: (Compiler evaluate: anExpression asString). + ^ self result! Item was added: + TestCase subclass: #TextEditorTest + instanceVariableNames: 'model widget' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Text Support'! Item was added: + ----- Method: TextEditorTest>>editor (in category 'running') ----- + editor + + ^ widget textMorph editor! Item was added: + ----- Method: TextEditorTest>>setUp (in category 'running') ----- + setUp + + super setUp. + model := MorphicTestTextModel new. + widget := PluggableTextMorph on: model text: #contents accept: #contents:. + + "We don't do real keyboard event handling. To be sure to set the model in the editor." + self editor model: model. + + model contents: ''.! Item was added: + ----- Method: TextEditorTest>>test01Setup (in category 'tests') ----- + test01Setup + + self assert: model dependents size = 1. + self assert: self editor model == model. + self assert: widget text isEmpty. + self assert: model contents isEmpty.! Item was added: + ----- Method: TextEditorTest>>test02EvaluateExpression (in category 'tests') ----- + test02EvaluateExpression + + model := MorphicTestTextModelWithEvaluationSupport new. + widget model: model. + + self text: '3+4'. + self editor doIt. + + self + assert: (model hasFlag: #expressionEvaluated); + assert: 7 equals: model result.! Item was added: + ----- Method: TextEditorTest>>test03DebugExpression (in category 'tests') ----- + test03DebugExpression + + self text: 'Morph new'. + self editor debugIt. + + self + assert: (model hasFlag: #expressionDebugged); + assert: (model result isKindOf: Morph).! Item was added: + ----- Method: TextEditorTest>>test04PrintIt (in category 'tests') ----- + test04PrintIt + + self text: '3+4'. + self editor printIt. + + self + assert: (model hasFlag: #printed); + assert: '7' equals: model result.! Item was added: + ----- Method: TextEditorTest>>test05ExploreIt (in category 'tests') ----- + test05ExploreIt + + self text: '1@1 corner: 20@20'. + self editor exploreIt. + + self + assert: (model hasFlag: #explored); + assert: (model result isKindOf: Rectangle).! Item was added: + ----- Method: TextEditorTest>>test06InspectIt (in category 'tests') ----- + test06InspectIt + + self text: '1@1 corner: 20@20'. + self editor inspectIt. + + self + assert: (model hasFlag: #inspected); + assert: (model result isKindOf: Rectangle).! Item was added: + ----- Method: TextEditorTest>>test07DoItReceiver (in category 'tests') ----- + test07DoItReceiver + + self text: 'self color'. + model result: (Morph new color: Color yellow). + self editor doIt. + + self + assert: (model hasFlag: #expressionEvaluated); + assert: Color yellow equals: model result.! Item was added: + ----- Method: TextEditorTest>>text: (in category 'running') ----- + text: aString + "Text editors have a short lifetime in pluggable text morphs." + + model contents: aString. + + "We don't do real keyboard event handling. To be sure to set the model in the editor." + self editor model: model.! From marcel.taeumel at student.hpi.uni-potsdam.de Fri May 1 09:41:55 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri May 1 09:57:08 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-mt.895.mcz In-Reply-To: References: Message-ID: <1430473315338-4823484.post@n4.nabble.com> Hi, you're right. #evaluate: is too generic if the text editor knows that it actually is an expression. I updated it: http://forum.world.st/The-Trunk-Morphic-mt-953-mcz-td4823480.html I also added some tests for TextEditor that capture the usage of those hooks. There are other strange things in TextEditor (e.g. #browseItHere) that indicate that those and similar model callbacks where missing. One goal should be to make the interface of text editors tool-agnostic. Best, Marcel -- View this message in context: http://forum.world.st/Re-The-Trunk-Morphic-mt-895-mcz-tp4823399p4823484.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Fri May 1 12:27:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 12:27:23 2015 Subject: [squeak-dev] The Trunk: EToys-mt.124.mcz Message-ID: Marcel Taeumel uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-mt.124.mcz ==================== Summary ==================== Name: EToys-mt.124 Author: mt Time: 1 May 2015, 2:27:02.944 pm UUID: 883ff941-bc6b-c940-87e9-d6a3c79c8443 Ancestors: EToys-topa.123 Tiles-view check moved from Tools package. =============== Diff against EToys-topa.123 =============== Item was changed: SystemOrganization addCategory: #'Etoys-Buttons'! SystemOrganization addCategory: #'Etoys-CustomEvents'! SystemOrganization addCategory: #'Etoys-Experimental'! SystemOrganization addCategory: #'Etoys-Outliner'! + SystemOrganization addCategory: #'Etoys-PreferenceBrowser'! SystemOrganization addCategory: #'Etoys-Protocols'! SystemOrganization addCategory: #'Etoys-Protocols-Type Vocabularies'! SystemOrganization addCategory: #'Etoys-Scripting'! SystemOrganization addCategory: #'Etoys-Scripting Support'! SystemOrganization addCategory: #'Etoys-Scripting Tiles'! SystemOrganization addCategory: #'Etoys-Stacks'! SystemOrganization addCategory: #'Etoys-StarSqueak'! SystemOrganization addCategory: #'Etoys-Support'! SystemOrganization addCategory: #'Etoys-Tests'! SystemOrganization addCategory: #'Etoys-Tile Scriptors'! SystemOrganization addCategory: #'Etoys-Widgets'! - SystemOrganization addCategory: #'Etoys-PreferenceBrowser'! Item was added: + ----- Method: CodeHolder>>showingTiles (in category '*Etoys-tiles') ----- + showingTiles + "Answer whether the receiver is currently showing tiles" + + ^ contentsSymbol == #tiles + ! From commits at source.squeak.org Fri May 1 12:28:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 12:28:57 2015 Subject: [squeak-dev] The Trunk: MorphicExtras-mt.162.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicExtras to project The Trunk: http://source.squeak.org/trunk/MorphicExtras-mt.162.mcz ==================== Summary ==================== Name: MorphicExtras-mt.162 Author: mt Time: 1 May 2015, 2:28:34.974 pm UUID: 784bd1ad-62dc-1b4d-89d6-5fa506031d2c Ancestors: MorphicExtras-mt.161 Added from Morph package. =============== Diff against MorphicExtras-mt.161 =============== Item was added: + ----- Method: Morph>>nextOwnerPage (in category '*MorphicExtras') ----- + nextOwnerPage + "Tell my container to advance to the next page" + | targ | + targ := self ownerThatIsA: BookMorph. + targ ifNotNil: [targ nextPage]! Item was added: + ----- Method: Morph>>previousOwnerPage (in category '*MorphicExtras') ----- + previousOwnerPage + "Tell my container to advance to the previous page" + | targ | + targ := self ownerThatIsA: BookMorph. + targ ifNotNil: [targ previousPage]! From commits at source.squeak.org Fri May 1 12:31:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 12:31:16 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.954.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.954.mcz ==================== Summary ==================== Name: Morphic-mt.954 Author: mt Time: 1 May 2015, 2:30:32.642 pm UUID: 45cdee2d-1fbe-fd42-8990-b204902bdd56 Ancestors: Morphic-mt.953 Deprecations updated and some dependencies to MorphicExtras removed. =============== Diff against Morphic-mt.953 =============== Item was removed: - ----- Method: Morph>>nextOwnerPage (in category 'geometry') ----- - nextOwnerPage - "Tell my container to advance to the next page" - | targ | - targ := self ownerThatIsA: BookMorph. - targ ifNotNil: [targ nextPage]! Item was removed: - ----- Method: Morph>>previousOwnerPage (in category 'geometry') ----- - previousOwnerPage - "Tell my container to advance to the previous page" - | targ | - targ := self ownerThatIsA: BookMorph. - targ ifNotNil: [targ previousPage]! Item was removed: - ----- Method: MorphicProject>>exportSegmentWithCatagories:classes:fileName:directory: (in category 'file in/out') ----- - exportSegmentWithCatagories: catList classes: classList fileName: aFileName directory: aDirectory - "Store my project out on the disk as an *exported* ImageSegment. All outPointers will be in a form that can be resolved in the target image. Name it .extSeg. What do we do about subProjects, especially if they are out as local image segments? Force them to come in? - Player classes are included automatically." - - | is str ans revertSeg roots holder | - self flag: #toRemove. - self halt. "unused" - "world == World ifTrue: [^ false]." - "self inform: 'Can''t send the current world out'." - world ifNil: [^ false]. world presenter ifNil: [^ false]. - - ScrapBook default emptyScrapBook. - world currentHand pasteBuffer: nil. "don't write the paste buffer." - world currentHand mouseOverHandler initialize. "forget about any references here" - "Display checkCurrentHandForObjectToPaste." - Command initialize. - world clearCommandHistory. - world fullReleaseCachedState; releaseViewers. - world cleanseStepList. - world localFlapTabs size = world flapTabs size ifFalse: [ - self error: 'Still holding onto Global flaps']. - world releaseSqueakPages. - holder := Project allProjects. "force them in to outPointers, where DiskProxys are made" - - "Just export me, not my previous version" - revertSeg := self parameterAt: #revertToMe. - self projectParameters removeKey: #revertToMe ifAbsent: []. - - roots := OrderedCollection new. - roots add: self; add: world; add: transcript; add: changeSet; add: thumbnail. - roots add: world activeHand; addAll: classList; addAll: (classList collect: [:cls | cls class]). - - roots := roots reject: [ :x | x isNil]. "early saves may not have active hand or thumbnail" - - catList do: [:sysCat | - (SystemOrganization listAtCategoryNamed: sysCat asSymbol) do: [:symb | - roots add: (Smalltalk at: symb); add: (Smalltalk at: symb) class]]. - - is := ImageSegment new copySmartRootsExport: roots asArray. - "old way was (is := ImageSegment new copyFromRootsForExport: roots asArray)" - - is state = #tooBig ifTrue: [^ false]. - - str := ''. - "considered legal to save a project that has never been entered" - (is outPointers includes: world) ifTrue: [ - str := str, '\Project''s own world is not in the segment.' withCRs]. - str isEmpty ifFalse: [ - ans := (UIManager default - chooseFrom: #('Do not write file' 'Write file anyway' 'Debug') - title: str). - ans = 1 ifTrue: [ - revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. - ^ false]. - ans = 3 ifTrue: [self halt: 'Segment not written']]. - - is writeForExportWithSources: aFileName inDirectory: aDirectory. - revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. - holder. - world flapTabs do: [:ft | - (ft respondsTo: #unhibernate) ifTrue: [ft unhibernate]]. - is arrayOfRoots do: [:obj | - obj isScriptEditorMorph ifTrue: [obj unhibernate]]. - ^ true - ! Item was removed: - ----- Method: ScrollPane>>alwaysShowHScrollBar: (in category 'DEPRECATED') ----- - alwaysShowHScrollBar: bool - self flag: #deprecated. - self setProperty: #hScrollBarAlways toValue: bool. - - bool - ifTrue: [self hScrollBarPolicy: #always] - ifFalse: [self hScrollBarPolicy: #whenNeeded]. - - self hHideOrShowScrollBar. - ! Item was removed: - ----- Method: ScrollPane>>alwaysShowScrollBars: (in category 'DEPRECATED') ----- - alwaysShowScrollBars: bool - "Get rid of scroll bar for short panes that don't want it shown." - - self flag: #deprecated. - - self - alwaysShowHScrollBar: bool; - alwaysShowVScrollBar: bool. - ! Item was removed: - ----- Method: ScrollPane>>alwaysShowVScrollBar: (in category 'DEPRECATED') ----- - alwaysShowVScrollBar: bool - - self flag: #deprecated. - - self setProperty: #vScrollBarAlways toValue: bool. - - bool - ifTrue: [self vScrollBarPolicy: #always] - ifFalse: [self vScrollBarPolicy: #whenNeeded]. - - self vHideOrShowScrollBar. - ! Item was removed: - ----- Method: ScrollPane>>hInitScrollBarTEMPORARY (in category 'DEPRECATED') ----- - hInitScrollBarTEMPORARY - "This is called lazily before the hScrollBar is accessed in a couple of places. It is provided to transition old ScrollPanes lying around that do not have an hScrollBar. Once it has been in the image for awhile, and all ScrollPanes have an hScrollBar, this method and it's references can be removed. " - - "Temporary method for filein of changeset" - hScrollBar ifNil: - [hScrollBar := ScrollBar new model: self slotName: 'hScrollBar'. - hScrollBar borderWidth: 1; borderColor: Color black. - self - resizeScrollBars; - setScrollDeltas; - hideOrShowScrollBars]. - ! Item was removed: - ----- Method: ScrollPane>>hideHScrollBarIndefinitely: (in category 'DEPRECATED') ----- - hideHScrollBarIndefinitely: bool - "Get rid of scroll bar for short panes that don't want it shown." - - self flag: #deprecated. - - self setProperty: #noHScrollBarPlease toValue: bool. - - bool - ifTrue: [self hScrollBarPolicy: #never] - ifFalse: [self hScrollBarPolicy: #whenNeeded]. - - self hHideOrShowScrollBar. - ! Item was removed: - ----- Method: ScrollPane>>hideScrollBarsIndefinitely: (in category 'DEPRECATED') ----- - hideScrollBarsIndefinitely: bool - "Get rid of scroll bar for short panes that don't want it shown." - - self flag: #deprecated. - - self hideVScrollBarIndefinitely: bool. - self hideHScrollBarIndefinitely: bool. - ! Item was removed: - ----- Method: ScrollPane>>hideVScrollBarIndefinitely: (in category 'DEPRECATED') ----- - hideVScrollBarIndefinitely: bool - "Get rid of scroll bar for short panes that don't want it shown." - - self flag: #deprecated. - - self setProperty: #noVScrollBarPlease toValue: bool. - - bool - ifTrue: [self vScrollBarPolicy: #never] - ifFalse: [self vScrollBarPolicy: #whenNeeded]. - - self vHideOrShowScrollBar. - ! Item was removed: - ----- Method: ScrollPane>>isAScrollbarShowing (in category 'DEPRECATED') ----- - isAScrollbarShowing - "Return true if a either retractable scroll bar is currently showing" - - self flag: #deprectaed. "mt: Use #isAnyScrollbarShowing" - retractableScrollBar ifFalse:[^true]. - ^self hIsScrollbarShowing or: [self vIsScrollbarShowing] - ! Item was removed: - ----- Method: ScrollPane>>showHScrollBarOnlyWhenNeeded: (in category 'DEPRECATED') ----- - showHScrollBarOnlyWhenNeeded: bool - "Get rid of scroll bar for short panes that don't want it shown." - - self flag: #deprecated. - - self setProperty: #noHScrollBarPlease toValue: bool not. - self setProperty: #hScrollBarAlways toValue: bool not. - - bool - ifTrue: [self hScrollBarPolicy: #whenNeeded] - ifFalse: [self hScrollBarPolicy: #never]. - - self hHideOrShowScrollBar. - ! Item was removed: - ----- Method: ScrollPane>>showScrollBarsOnlyWhenNeeded: (in category 'DEPRECATED') ----- - showScrollBarsOnlyWhenNeeded: bool - - self flag: #deprecated. - - self showHScrollBarOnlyWhenNeeded: bool. - self showVScrollBarOnlyWhenNeeded: bool. - ! Item was removed: - ----- Method: ScrollPane>>showVScrollBarOnlyWhenNeeded: (in category 'DEPRECATED') ----- - showVScrollBarOnlyWhenNeeded: bool - "Get rid of scroll bar for short panes that don't want it shown." - - self flag: #deprecated. - - self setProperty: #noVScrollBarPlease toValue: bool not. - self setProperty: #vScrollBarAlways toValue: bool not. - - bool - ifTrue: [self vScrollBarPolicy: #whenNeeded] - ifFalse: [self vScrollBarPolicy: #never]. - - self vHideOrShowScrollBar. - ! From commits at source.squeak.org Fri May 1 12:32:42 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 12:32:44 2015 Subject: [squeak-dev] The Trunk: Tools-mt.613.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.613.mcz ==================== Summary ==================== Name: Tools-mt.613 Author: mt Time: 1 May 2015, 2:32:16.632 pm UUID: e0697d0b-8eb9-5647-81bd-922a24eb997f Ancestors: Tools-mt.612 Deprecations updated. =============== Diff against Tools-mt.612 =============== Item was changed: ----- Method: Browser>>arrowKey:from: (in category 'multi-window support') ----- arrowKey: aChar from: view "Intercept Apple-Digit to select panes" | index | (aChar isDigit + and: [self multiWindowState notNil]) ifTrue: - and: [multiWindowState notNil]) ifTrue: [index := aChar asciiValue - $0 asciiValue. index = 0 ifTrue: [index := 10]. + ^index <= self multiWindowState models size + ifTrue: [self multiWindowState selectWindowIndex: index] - ^index <= multiWindowState models size - ifTrue: [multiWindowState selectWindowIndex: index] ifFalse: [self changed: #flash]]. ^super arrowKey: aChar from: view ! Item was removed: - ----- Method: Browser>>classComment:notifying: (in category 'class comment pane') ----- - classComment: aText notifying: aPluggableTextMorph - "The user has just entered aText. - It may be all red (a side-effect of replacing the default comment), so remove the color if it is." - - | theClass cleanedText redRange | - theClass := self selectedClassOrMetaClass. - theClass - ifNotNil: [cleanedText := aText asText. - redRange := cleanedText rangeOf: TextColor red startingAt: 1. - redRange size = cleanedText size - ifTrue: [cleanedText - removeAttribute: TextColor red - from: 1 - to: redRange last ]. - theClass comment: aText stamp: Utilities changeStamp]. - self changed: #classCommentText. - ^ true! Item was changed: ----- Method: Browser>>classHierarchy (in category 'multi-window support') ----- classHierarchy | behavior newBrowser | (behavior := self selectedClassOrMetaClass) isNil ifTrue: [^self]. (self isPackage "PackageBrowser pains can't support a hierarchy browser; not sure why." + or: [self multiWindowState isNil]) ifTrue: - or: [multiWindowState isNil]) ifTrue: [^super classHierarchy]. (newBrowser := HierarchyBrowser new initHierarchyForClass: behavior) selectMessageCategoryNamed: self selectedMessageCategoryName; selectMessageNamed: self selectedMessageName; editSelection: editSelection. + self multiWindowState addWindow: newBrowser - multiWindowState addWindow: newBrowser ! Item was removed: - ----- Method: Browser>>defineMessage:notifying: (in category 'message functions') ----- - defineMessage: aString notifying: aController - self deprecated: 'Use Browser >> #defineMessageFrom:notifying:. This returns a Symbol or nil, not a Boolean.'. - ^ (self defineMessageFrom: aString notifying: aController) notNil.! Item was changed: ----- Method: Browser>>findClass (in category 'system category functions') ----- findClass "Search for a class by name." | foundClass | + (self multiWindowState notNil - (multiWindowState notNil or: [self okToChange]) ifFalse: [^self classNotFound]. foundClass := UIManager default chooseClassOrTrait. foundClass ifNil: [^self classNotFound]. (self selectedClass notNil + and: [self multiWindowState notNil - and: [multiWindowState notNil "Can only support multi-window if original window has all the right panes." + and: [self multiWindowState prototype isHierarchy not]]) ifTrue: - and: [multiWindowState prototype isHierarchy not]]) ifTrue: [(self classList includes: foundClass name) + ifTrue: [self multiWindowState copyWindow] + ifFalse: [self multiWindowState addNewWindow]]. - ifTrue: [multiWindowState copyWindow] - ifFalse: [multiWindowState addNewWindow]]. self selectCategoryForClass: foundClass. self selectClass: foundClass! Item was changed: ----- Method: Browser>>labelString (in category 'initialize-release') ----- labelString | label | label := self selectedClassName ifNil: [ self defaultBrowserTitle ] ifNotNil: [ self defaultBrowserTitle, ': ', self selectedClassName asString ]. + (self multiWindowState notNil + and: [self multiWindowState models size > 1]) ifTrue: + [label := (self multiWindowState models indexOf: self) printString, '. ', label]. - (multiWindowState notNil - and: [multiWindowState models size > 1]) ifTrue: - [label := (multiWindowState models indexOf: self) printString, '. ', label]. ^label! Item was removed: - ----- Method: Browser>>messageListSingleton (in category 'message list') ----- - messageListSingleton - - | name | - name := self selectedMessageName. - ^ name ifNil: [Array new] - ifNotNil: [Array with: name]! Item was changed: ----- Method: Browser>>okToClose (in category 'multi-window support') ----- okToClose ^super okToClose + and: [self multiWindowState isNil or: [self multiWindowState okToClose]]! - and: [multiWindowState isNil or: [multiWindowState okToClose]]! Item was removed: - ----- Method: Browser>>optionalAnnotationHeight (in category 'initialize-release') ----- - optionalAnnotationHeight - - ^ 10! Item was removed: - ----- Method: Browser>>optionalButtonHeight (in category 'initialize-release') ----- - optionalButtonHeight - - ^ 10! Item was removed: - ----- Method: Browser>>potentialClassNames (in category 'system category functions') ----- - potentialClassNames - "Answer the names of all the classes that could be viewed in this browser. This hook is provided so that HierarchyBrowsers can indicate their restricted subset. For generic Browsers, the entire list of classes known to Smalltalk is provided, though of course that really only is accurate in the case of full system browsers." - - ^ Smalltalk classNames! Item was removed: - ----- Method: CodeHolder>>abbreviatedWordingFor: (in category 'commands') ----- - abbreviatedWordingFor: aButtonSelector - "Answer the abbreviated form of wording, from a static table. Answer nil if there is no entry -- in which case the long form will be used on the corresponding browser button." - - #( - (browseMethodFull 'browse') - (browseSendersOfMessages 'senders') - (browseMessages 'impl') - (browseVersions 'vers') - (methodHierarchy 'inher') - (classHierarchy 'hier') - (browseVariableReferences 'refs') - (offerMenu 'menu')) do: - - [:pair | pair first == aButtonSelector ifTrue: [^ pair second]]. - ^ nil! Item was changed: ----- Method: CodeHolder>>buildCodeProvenanceButtonWith: (in category 'toolbuilder') ----- buildCodeProvenanceButtonWith: builder | buttonSpec | buttonSpec := builder pluggableActionButtonSpec new. + buttonSpec + model: self; + label: #codePaneProvenanceString; + changeLabelWhen: #contents; + style: #menuButton; + action: #offerWhatToShowMenu; + help: 'Governs what view is shown in the code pane. Click here to change the view'; + margin: (5@0 corner: 0@0). - buttonSpec model: self. - buttonSpec label: #codePaneProvenanceString. - buttonSpec changeLabelWhen: #contents. - buttonSpec style: #menuButton. - buttonSpec action: #offerWhatToShowMenu. - buttonSpec help: 'Governs what view is shown in the code pane. Click here to change the view'. ^buttonSpec! Item was changed: ----- Method: CodeHolder>>restoreTextualCodingPane (in category 'diffs') ----- restoreTextualCodingPane "If the receiver is showing tiles, restore the textual coding pane" + contentsSymbol == #tiles ifTrue: - self showingTiles ifTrue: [contentsSymbol := #source. self installTextualCodingPane]! Item was removed: - ----- Method: CodeHolder>>showingDiffsString (in category 'diffs') ----- - showingDiffsString - "Answer a string representing whether I'm showing diffs. Not sent any more but retained so that prexisting buttons that sent this will not raise errors." - - ^ (self showingRegularDiffs - ifTrue: - [''] - ifFalse: - ['']), 'showDiffs'! Item was removed: - ----- Method: CodeHolder>>showingTiles (in category 'diffs') ----- - showingTiles - "Answer whether the receiver is currently showing tiles" - - ^ contentsSymbol == #tiles - ! Item was removed: - ----- Method: CodeHolder>>toggleDiff (in category 'diffs') ----- - toggleDiff - "Retained for backward compatibility with existing buttons in existing images" - - self toggleDiffing! Item was removed: - ----- Method: HierarchyBrowser>>potentialClassNames (in category 'initialization') ----- - potentialClassNames - "Answer the names of all the classes that could be viewed in this browser" - ^ self classList collect: - [:aName | aName copyWithout: $ ]! Item was changed: ----- Method: PackagePaneBrowser>>labelString (in category 'initialize-release') ----- labelString ^self package ifNil: [super labelString] ifNotNil: [:pkg| | label | label := self defaultBrowserTitle, ': ', pkg, (self selectedClass ifNil: [''] ifNotNil: [' ', self selectedClass printString]). + (self multiWindowState notNil + and: [self multiWindowState models size > 1]) ifTrue: + [label := (self multiWindowState models indexOf: self) printString, '. ', label]. - (multiWindowState notNil - and: [multiWindowState models size > 1]) ifTrue: - [label := (multiWindowState models indexOf: self) printString, '. ', label]. label]! From commits at source.squeak.org Fri May 1 12:33:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 12:33:14 2015 Subject: [squeak-dev] The Trunk: 46Deprecated-mt.1.mcz Message-ID: Marcel Taeumel uploaded a new version of 46Deprecated to project The Trunk: http://source.squeak.org/trunk/46Deprecated-mt.1.mcz ==================== Summary ==================== Name: 46Deprecated-mt.1 Author: mt Time: 1 May 2015, 2:33:12.046 pm UUID: a2c7055c-a7ec-4442-b80a-8e076a79e39c Ancestors: Some deprecations for 4.6 added. ==================== Snapshot ==================== ----- Method: MorphicProject>>exportSegmentWithCatagories:classes:fileName:directory: (in category '*46Deprecated') ----- exportSegmentWithCatagories: catList classes: classList fileName: aFileName directory: aDirectory "Store my project out on the disk as an *exported* ImageSegment. All outPointers will be in a form that can be resolved in the target image. Name it .extSeg. What do we do about subProjects, especially if they are out as local image segments? Force them to come in? Player classes are included automatically." | is str ans revertSeg roots holder | self flag: #toRemove. self halt. "unused" "world == World ifTrue: [^ false]." "self inform: 'Can''t send the current world out'." world ifNil: [^ false]. world presenter ifNil: [^ false]. ScrapBook default emptyScrapBook. world currentHand pasteBuffer: nil. "don't write the paste buffer." world currentHand mouseOverHandler initialize. "forget about any references here" "Display checkCurrentHandForObjectToPaste." Command initialize. world clearCommandHistory. world fullReleaseCachedState; releaseViewers. world cleanseStepList. world localFlapTabs size = world flapTabs size ifFalse: [ self error: 'Still holding onto Global flaps']. world releaseSqueakPages. holder := Project allProjects. "force them in to outPointers, where DiskProxys are made" "Just export me, not my previous version" revertSeg := self parameterAt: #revertToMe. self projectParameters removeKey: #revertToMe ifAbsent: []. roots := OrderedCollection new. roots add: self; add: world; add: transcript; add: changeSet; add: thumbnail. roots add: world activeHand; addAll: classList; addAll: (classList collect: [:cls | cls class]). roots := roots reject: [ :x | x isNil]. "early saves may not have active hand or thumbnail" catList do: [:sysCat | (SystemOrganization listAtCategoryNamed: sysCat asSymbol) do: [:symb | roots add: (Smalltalk at: symb); add: (Smalltalk at: symb) class]]. is := ImageSegment new copySmartRootsExport: roots asArray. "old way was (is := ImageSegment new copyFromRootsForExport: roots asArray)" is state = #tooBig ifTrue: [^ false]. str := ''. "considered legal to save a project that has never been entered" (is outPointers includes: world) ifTrue: [ str := str, '\Project''s own world is not in the segment.' withCRs]. str isEmpty ifFalse: [ ans := (UIManager default chooseFrom: #('Do not write file' 'Write file anyway' 'Debug') title: str). ans = 1 ifTrue: [ revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. ^ false]. ans = 3 ifTrue: [self halt: 'Segment not written']]. is writeForExportWithSources: aFileName inDirectory: aDirectory. revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. holder. world flapTabs do: [:ft | (ft respondsTo: #unhibernate) ifTrue: [ft unhibernate]]. is arrayOfRoots do: [:obj | obj isScriptEditorMorph ifTrue: [obj unhibernate]]. ^ true ! ----- Method: Browser>>classComment:notifying: (in category '*46Deprecated') ----- classComment: aText notifying: aPluggableTextMorph "The user has just entered aText. It may be all red (a side-effect of replacing the default comment), so remove the color if it is." | theClass cleanedText redRange | theClass := self selectedClassOrMetaClass. theClass ifNotNil: [cleanedText := aText asText. redRange := cleanedText rangeOf: TextColor red startingAt: 1. redRange size = cleanedText size ifTrue: [cleanedText removeAttribute: TextColor red from: 1 to: redRange last ]. theClass comment: aText stamp: Utilities changeStamp]. self changed: #classCommentText. ^ true! ----- Method: Browser>>defineMessage:notifying: (in category '*46Deprecated') ----- defineMessage: aString notifying: aController self deprecated: 'Use Browser >> #defineMessageFrom:notifying:. This returns a Symbol or nil, not a Boolean.'. ^ (self defineMessageFrom: aString notifying: aController) notNil.! ----- Method: Browser>>messageListSingleton (in category '*46Deprecated') ----- messageListSingleton | name | name := self selectedMessageName. ^ name ifNil: [Array new] ifNotNil: [Array with: name]! ----- Method: Browser>>optionalAnnotationHeight (in category '*46Deprecated') ----- optionalAnnotationHeight ^ 10! ----- Method: Browser>>optionalButtonHeight (in category '*46Deprecated') ----- optionalButtonHeight ^ 10! ----- Method: Browser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser. This hook is provided so that HierarchyBrowsers can indicate their restricted subset. For generic Browsers, the entire list of classes known to Smalltalk is provided, though of course that really only is accurate in the case of full system browsers." ^ Smalltalk classNames! ----- Method: CodeHolder>>abbreviatedWordingFor: (in category '*46Deprecated') ----- abbreviatedWordingFor: aButtonSelector "Answer the abbreviated form of wording, from a static table. Answer nil if there is no entry -- in which case the long form will be used on the corresponding browser button." #( (browseMethodFull 'browse') (browseSendersOfMessages 'senders') (browseMessages 'impl') (browseVersions 'vers') (methodHierarchy 'inher') (classHierarchy 'hier') (browseVariableReferences 'refs') (offerMenu 'menu')) do: [:pair | pair first == aButtonSelector ifTrue: [^ pair second]]. ^ nil! ----- Method: CodeHolder>>showingDiffsString (in category '*46Deprecated') ----- showingDiffsString "Answer a string representing whether I'm showing diffs. Not sent any more but retained so that prexisting buttons that sent this will not raise errors." ^ (self showingRegularDiffs ifTrue: [''] ifFalse: ['']), 'showDiffs'! ----- Method: CodeHolder>>toggleDiff (in category '*46Deprecated') ----- toggleDiff "Retained for backward compatibility with existing buttons in existing images" self toggleDiffing! ----- Method: HierarchyBrowser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser" ^ self classList collect: [:aName | aName copyWithout: $ ]! ----- Method: ScrollPane>>alwaysShowHScrollBar: (in category '*46Deprecated') ----- alwaysShowHScrollBar: bool self flag: #deprecated. self setProperty: #hScrollBarAlways toValue: bool. bool ifTrue: [self hScrollBarPolicy: #always] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>alwaysShowScrollBars: (in category '*46Deprecated') ----- alwaysShowScrollBars: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self alwaysShowHScrollBar: bool; alwaysShowVScrollBar: bool. ! ----- Method: ScrollPane>>alwaysShowVScrollBar: (in category '*46Deprecated') ----- alwaysShowVScrollBar: bool self flag: #deprecated. self setProperty: #vScrollBarAlways toValue: bool. bool ifTrue: [self vScrollBarPolicy: #always] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>hInitScrollBarTEMPORARY (in category '*46Deprecated') ----- hInitScrollBarTEMPORARY "This is called lazily before the hScrollBar is accessed in a couple of places. It is provided to transition old ScrollPanes lying around that do not have an hScrollBar. Once it has been in the image for awhile, and all ScrollPanes have an hScrollBar, this method and it's references can be removed. " "Temporary method for filein of changeset" hScrollBar ifNil: [hScrollBar := ScrollBar new model: self slotName: 'hScrollBar'. hScrollBar borderWidth: 1; borderColor: Color black. self resizeScrollBars; setScrollDeltas; hideOrShowScrollBars]. ! ----- Method: ScrollPane>>hideHScrollBarIndefinitely: (in category '*46Deprecated') ----- hideHScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool. bool ifTrue: [self hScrollBarPolicy: #never] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>hideScrollBarsIndefinitely: (in category '*46Deprecated') ----- hideScrollBarsIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self hideVScrollBarIndefinitely: bool. self hideHScrollBarIndefinitely: bool. ! ----- Method: ScrollPane>>hideVScrollBarIndefinitely: (in category '*46Deprecated') ----- hideVScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool. bool ifTrue: [self vScrollBarPolicy: #never] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>isAScrollbarShowing (in category '*46Deprecated') ----- isAScrollbarShowing "Return true if a either retractable scroll bar is currently showing" self flag: #deprectaed. "mt: Use #isAnyScrollbarShowing" retractableScrollBar ifFalse:[^true]. ^self hIsScrollbarShowing or: [self vIsScrollbarShowing] ! ----- Method: ScrollPane>>showHScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showHScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool not. self setProperty: #hScrollBarAlways toValue: bool not. bool ifTrue: [self hScrollBarPolicy: #whenNeeded] ifFalse: [self hScrollBarPolicy: #never]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>showScrollBarsOnlyWhenNeeded: (in category '*46Deprecated') ----- showScrollBarsOnlyWhenNeeded: bool self flag: #deprecated. self showHScrollBarOnlyWhenNeeded: bool. self showVScrollBarOnlyWhenNeeded: bool. ! ----- Method: ScrollPane>>showVScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showVScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool not. self setProperty: #vScrollBarAlways toValue: bool not. bool ifTrue: [self vScrollBarPolicy: #whenNeeded] ifFalse: [self vScrollBarPolicy: #never]. self vHideOrShowScrollBar. ! From marcel.taeumel at student.hpi.uni-potsdam.de Fri May 1 12:23:15 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri May 1 12:38:29 2015 Subject: [squeak-dev] Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk Message-ID: <1430482995005-4823540.post@n4.nabble.com> Hi --- We should unload all historic deprecations... and focus on what is needed for 46Deprecated (if it cannot be deleted). Best, Marcel -- View this message in context: http://forum.world.st/Unload-39Deprecated-311Deprecated-and-45Deprecated-in-Trunk-tp4823540.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From nicolas.cellier.aka.nice at gmail.com Fri May 1 13:00:39 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Fri May 1 13:00:42 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-mt.895.mcz In-Reply-To: <1430473315338-4823484.post@n4.nabble.com> References: <1430473315338-4823484.post@n4.nabble.com> Message-ID: Thanks Marcel, that was fast! sometimes I wonder if the fix will not be in the trunk before i ever complain ;) Most often it is already in the trunk :) 2015-05-01 11:41 GMT+02:00 Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de>: > Hi, > > you're right. #evaluate: is too generic if the text editor knows that it > actually is an expression. I updated it: > http://forum.world.st/The-Trunk-Morphic-mt-953-mcz-td4823480.html > > I also added some tests for TextEditor that capture the usage of those > hooks. > > There are other strange things in TextEditor (e.g. #browseItHere) that > indicate that those and similar model callbacks where missing. One goal > should be to make the interface of text editors tool-agnostic. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/Re-The-Trunk-Morphic-mt-895-mcz-tp4823399p4823484.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150501/7865aecd/attachment.htm From commits at source.squeak.org Fri May 1 13:09:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 13:09:58 2015 Subject: [squeak-dev] The Trunk: Kernel-nice.921.mcz Message-ID: Nicolas Cellier uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-nice.921.mcz ==================== Summary ==================== Name: Kernel-nice.921 Author: nice Time: 1 May 2015, 3:09:15.528 pm UUID: 1ce76bf5-1e32-4d12-b7b1-9f23a75d37b2 Ancestors: Kernel-topa.920 Provide an exact version for #floorLog: for those Number using exact arithmetic (as proposed in inbox Kernel-nice.721 / 11 December 2012). Previous version was not exact, otherwise this count would have been zero: (-300 to: -1) count: [:n | n ~= ((10 raisedTo: n) floorLog: 10)]. Note that this won't make #log: exact, and could lead to disagreement between the two functions. However, old behavior compatible with log: is still possible by passing the radix argument asFloat, so this is not a real problem. =============== Diff against Kernel-topa.920 =============== Item was added: + ----- Method: Fraction>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + | d n | + radix isInteger ifFalse: [^super floorLog: 10]. + n := numerator floorLog: radix. + d := denominator floorLog: radix. + ^(numerator * (radix raisedTo: d)) + < (denominator * (radix raisedTo: n)) + ifTrue: [n - d - 1] + ifFalse: [n - d]! Item was added: + ----- Method: Integer>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + radix isInteger ifFalse: [^super floorLog: 10]. + self <= 0 ifTrue: [^DomainError signal: 'floorLog: is only defined for x > 0.0']. + ^(self numberOfDigitsInBase: radix) - 1! Item was added: + ----- Method: ScaledDecimal>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + ^self asFraction floorLog: radix! From commits at source.squeak.org Fri May 1 13:17:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 13:17:12 2015 Subject: [squeak-dev] The Trunk: KernelTests-nice.293.mcz Message-ID: Nicolas Cellier uploaded a new version of KernelTests to project The Trunk: http://source.squeak.org/trunk/KernelTests-nice.293.mcz ==================== Summary ==================== Name: KernelTests-nice.293 Author: nice Time: 1 May 2015, 3:16:46.949 pm UUID: fb60846c-b40a-4f89-9ec5-1260cfbf0319 Ancestors: KernelTests-mt.292 Tests asserting floorLog: exactness for Number performing exact arithmetic. This was inbox KernelTests-nice.239 / 11 December 2012 =============== Diff against KernelTests-mt.292 =============== Item was added: + ----- Method: FractionTest>>testFloorLogExactness (in category 'tests - mathematical functions') ----- + testFloorLogExactness + + 1 + (Float fminDenormalized floorLog: 10) to: -1 do: [:n | + self assert: ((10 raisedTo: n) floorLog: 10) = n]. + + "Float version is not exact for at least 2 reasons: + 1/(10 raisedTo: n) asFloat is not exact + (aFloat log: radix) is not exact + + (1 + (Float fminDenormalized floorLog: 10) to: -1) count: [:n | + ((10 raisedTo: n) asFloat floorLog: 10) ~= n]." + ! Item was added: + ----- Method: IntegerTest>>testFloorLogExactness (in category 'tests - mathematical functions') ----- + testFloorLogExactness + + 1 to: (Float fmax floorLog: 10) do: [:n | + self assert: ((10 raisedTo: n) floorLog: 10) = n]. + + "Float version is not exact for at least 2 reasons: + (10 raisedTo: n) asFloat is not exact for n > 22 + (aFloat log: radix) is not exact + + (1 to: (Float fmax floorLog: 10)) count: [:n | + ((10 raisedTo: n) asFloat floorLog: 10) ~= n]."! Item was added: + ----- Method: ScaledDecimalTest>>testFloorLogExactness (in category 'tests - mathematical functions') ----- + testFloorLogExactness + 1 + (Float fminDenormalized floorLog: 10) to: (Float fmax floorLog: 10) do: [:n | + self assert: ((10 raisedTo: n) asScaledDecimal floorLog: 10) = n description: 'floorLog should be exact for ScaledDecimals'.]! From commits at source.squeak.org Fri May 1 13:25:36 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 13:25:39 2015 Subject: [squeak-dev] The Trunk: Kernel-nice.922.mcz Message-ID: Nicolas Cellier uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-nice.922.mcz ==================== Summary ==================== Name: Kernel-nice.922 Author: nice Time: 1 May 2015, 3:24:52.309 pm UUID: 609507cb-36a8-44cd-a2ab-368a7a8b6a02 Ancestors: Kernel-nice.921 Remove an un-necessary inst. var. shadowing (inbox Kernel-nice.745 7 March 2013) =============== Diff against Kernel-nice.921 =============== Item was changed: ----- Method: ContextPart>>asMessage (in category 'converting') ----- asMessage + | selector args | - | sender selector args | - sender := self sender. selector := sender method selector. args := Array new: selector numArgs. 1 to: selector numArgs do: [ :i | args at: i put: (sender tempAt: i)]. ^ Message selector: selector arguments: args.! From commits at source.squeak.org Fri May 1 13:33:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 13:33:30 2015 Subject: [squeak-dev] The Trunk: Kernel-nice.923.mcz Message-ID: Nicolas Cellier uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-nice.923.mcz ==================== Summary ==================== Name: Kernel-nice.923 Author: nice Time: 1 May 2015, 3:32:43.592 pm UUID: 875249b7-3037-4f50-9ab1-c1b2ec94b0e1 Ancestors: Kernel-nice.922 Use an intermediate abstract Float representation (sign, exponent, significand) in order to convert single precision bits to double precision bits rather than attempting the conversion by direct bit manipulations. This lead to simpler code, because it is like a semantic bit manipulation rather than a raw bit manipulation. And this also lead to faster code on 32 bits interpreter/COG/Spur VM thanks to avoidance of LargeInteger (was Kernel-nice.893 / 24 December 2014) =============== Diff against Kernel-nice.922 =============== Item was changed: ----- Method: Float class>>fromIEEE32Bit: (in category 'instance creation') ----- fromIEEE32Bit: word "Convert the given 32 bit word (which is supposed to be a positive 32bit value) from a 32bit IEEE floating point representation into an actual Squeak float object (being 64bit wide). Should only be used for conversion in FloatArrays or likewise objects." + | sign mantissa exponent | - | sign mantissa exponent newFloat delta | word negative ifTrue: [^ self error:'Cannot deal with negative numbers']. word = 0 ifTrue: [^ Float zero]. + word = 16r80000000 ifTrue: [^Float negativeZero]. - sign := word bitAnd: 16r80000000. - word = sign ifTrue: [^self negativeZero]. + sign := word bitShift: -31. exponent := ((word bitShift: -23) bitAnd: 16rFF) - 127. mantissa := word bitAnd: 16r7FFFFF. exponent = 128 ifTrue:["Either NAN or INF" mantissa = 0 ifFalse:[^ Float nan]. sign = 0 ifTrue:[^ Float infinity] ifFalse:[^ Float negativeInfinity]]. + exponent = -127 + ifTrue: + ["gradual underflow (denormalized number) + There is no implied one, but the exponent is -126" + exponent := -126] + ifFalse: + [mantissa := mantissa + 16r800000 "impliedOne"]. - exponent = -127 ifTrue: [ - "gradual underflow (denormalized number) - Remove first bit of mantissa and adjust exponent" - delta := mantissa highBit. - mantissa := (mantissa bitAnd: (1 bitShift: delta - 1) - 1) bitShift: 24 - delta. - exponent := exponent + delta - 23]. "Create new float" + ^(sign = 0 + ifTrue: [mantissa] + ifFalse: [mantissa negated]) + asFloat timesTwoPower: exponent - 23! - newFloat := self new: 2. - newFloat basicAt: 1 put: ((sign bitOr: (1023 + exponent bitShift: 20)) bitOr: (mantissa bitShift: -3)). - newFloat basicAt: 2 put: ((mantissa bitAnd: 7) bitShift: 29). - ^newFloat! From commits at source.squeak.org Fri May 1 13:39:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 13:40:00 2015 Subject: [squeak-dev] The Trunk: Collections-tfel.624.mcz Message-ID: Tim Felgentreff uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-tfel.624.mcz ==================== Summary ==================== Name: Collections-tfel.624 Author: tfel Time: 1 May 2015, 3:39:37.7 pm UUID: 5cb7424e-b88f-3b4e-beb3-c97639f2d91f Ancestors: Collections-tfel.623 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String =============== Diff against Collections-tfel.623 =============== Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! From asqueaker at gmail.com Fri May 1 14:48:49 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri May 1 14:48:52 2015 Subject: [squeak-dev] The Trunk: Collections-tfel.623.mcz In-Reply-To: <55434243.cda4340a.7c6c.29eeSMTPIN_ADDED_MISSING@mx.google.com> References: <55434243.cda4340a.7c6c.29eeSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: I know you are making the Smalltalk code behave teh same as the primitive but did you consider making the primitive behave the same as the Smalltalk code and signal an error? I dunno, if an app is going to calculate a starting position to search a String and gets it wrong, this code will quietly produce erroneous results. Such is the type of bug that could go unnoticed for a long time. This seems like one of those things that is low-level enough that an error should be signaled.. On Fri, May 1, 2015 at 4:06 AM, wrote: > Tim Felgentreff uploaded a new version of Collections to project The Trunk: > http://source.squeak.org/trunk/Collections-tfel.623.mcz > > ==================== Summary ==================== > > Name: Collections-tfel.623 > Author: tfel > Time: 1 May 2015, 11:06:35.625 am > UUID: baf2902d-52b9-2442-a513-8a5a6ff0ce30 > Ancestors: Collections-nice.622 > > fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 > > =============== Diff against Collections-nice.622 =============== > > Item was changed: > ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- > findSubstring: key in: body startingAt: start matchTable: matchTable > "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. > > The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." > | index | > > > > > > key size = 0 ifTrue: [^ 0]. > + (start max: 1) to: body size - key size + 1 do: > - start to: body size - key size + 1 do: > [:startIndex | > index := 1. > [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) > = (matchTable at: (key at: index) asciiValue + 1)] > whileTrue: > [index = key size ifTrue: [^ startIndex]. > index := index+1]]. > ^ 0 > " > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 > ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 > ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 > "! > > From marcel.taeumel at student.hpi.uni-potsdam.de Fri May 1 14:39:23 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri May 1 14:54:37 2015 Subject: [squeak-dev] Re: The Trunk: Collections-tfel.623.mcz In-Reply-To: References: Message-ID: <1430491163940-4823567.post@n4.nabble.com> The thing is that the primitive accepts indices < 1 has starting position. All projects that rely on this will fails if that primitive is not present. So -- and only for strings -- I guess it is fair to simulate the actual behavior of the primtive in case of a primtive-fail for strings only. So, this change will not harm existing projects but ensures that those keep on working if the primitive is not existing. Before that update, those projects failed unexpectedly. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-tfel-623-mcz-tp4823453p4823567.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From asqueaker at gmail.com Fri May 1 15:54:50 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri May 1 15:54:53 2015 Subject: [squeak-dev] Re: The Trunk: Collections-tfel.623.mcz In-Reply-To: <1430491163940-4823567.post@n4.nabble.com> References: <1430491163940-4823567.post@n4.nabble.com> Message-ID: On Fri, May 1, 2015 at 9:39 AM, Marcel Taeumel wrote: > The thing is that the primitive accepts indices < 1 has starting position. > All projects that rely on this will fails if that primitive is not present. > So -- and only for strings -- I guess it is fair to simulate the actual > behavior of the primtive in case of a primtive-fail for strings only. > > So, this change will not harm existing projects but ensures that those keep > on working if the primitive is not existing. Before that update, those > projects failed unexpectedly. Right, but that wasn't my question. From commits at source.squeak.org Fri May 1 15:56:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 15:56:56 2015 Subject: [squeak-dev] The Trunk: Collections-mt.625.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.625.mcz ==================== Summary ==================== Name: Collections-mt.625 Author: mt Time: 1 May 2015, 5:56:35.941 pm UUID: 0edce141-a23a-a845-a735-743f311112b2 Ancestors: Collections-tfel.624 Speed-up #endsWith: for strings. =============== Diff against Collections-tfel.624 =============== Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! From commits at source.squeak.org Fri May 1 16:00:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 16:00:09 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.955.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.955.mcz ==================== Summary ==================== Name: Morphic-mt.955 Author: mt Time: 1 May 2015, 5:59:25.636 pm UUID: 50c62168-fb76-e34e-955b-dc488b84049b Ancestors: Morphic-mt.954 Flag about a performance issue in scroll bars added. We should improve that at some point. =============== Diff against Morphic-mt.954 =============== Item was changed: ----- Method: ScrollBar>>sliderColor: (in category 'access') ----- sliderColor: aColor "Change the color of the scrollbar to go with aColor." | buttonColor | super sliderColor: aColor. self updateSliderColor: aColor. buttonColor := self thumbColor. self menuButton color: aColor. upButton color: aColor. downButton color: aColor. self class updateScrollBarButtonsAspect: {self menuButton. upButton. downButton} color: aColor. + self flag: #performance. "mt: This is slow..." self updateMenuButtonImage. self updateUpButtonImage. self updateDownButtonImage.! From commits at source.squeak.org Fri May 1 16:02:25 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 16:02:27 2015 Subject: [squeak-dev] The Trunk: Tools-mt.614.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.614.mcz ==================== Summary ==================== Name: Tools-mt.614 Author: mt Time: 1 May 2015, 6:02:03.582 pm UUID: d14a1b9e-198e-e549-931c-440d9c40d12c Ancestors: Tools-mt.613 Some descriptive balloon texts added to browser's switch buttons. =============== Diff against Tools-mt.613 =============== Item was changed: ----- Method: Browser>>buildSwitchesWith: (in category 'toolbuilder') ----- buildSwitchesWith: builder "Build the instance/comment/class switch" | panelSpec buttonSpec | panelSpec := builder pluggablePanelSpec new layout: #horizontal; children: OrderedCollection new; yourself. buttonSpec := builder pluggableButtonSpec new. buttonSpec model: self; + label: 'instance'; + help: 'Show instance-side methods' translated; - label: 'instance'; state: #instanceMessagesIndicated; action: #indicateInstanceMessages. panelSpec children addLast: buttonSpec. buttonSpec := builder pluggableButtonSpec new. buttonSpec model: self; label: '?'; help: 'Cycle between definition, comment, and hierarchy view' translated; state: #classCommentIndicated; action: #plusButtonHit. panelSpec children addLast: buttonSpec. buttonSpec := builder pluggableButtonSpec new. buttonSpec model: self; + label: 'class'; + help: 'Show class-side methods' translated; - label: 'class'; state: #classMessagesIndicated; action: #indicateClassMessages. panelSpec children addLast: buttonSpec. ^panelSpec! From commits at source.squeak.org Fri May 1 17:16:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 17:16:06 2015 Subject: [squeak-dev] The Trunk: SMLoader-mt.82.mcz Message-ID: Marcel Taeumel uploaded a new version of SMLoader to project The Trunk: http://source.squeak.org/trunk/SMLoader-mt.82.mcz ==================== Summary ==================== Name: SMLoader-mt.82 Author: mt Time: 1 May 2015, 7:15:59.365 pm UUID: 5a87a1e6-6cac-1649-874e-a92ad8bcdd1a Ancestors: SMLoader-cmm.81 Fixed layout problems and selection bugs in SqueakMap tools. =============== Diff against SMLoader-cmm.81 =============== Item was changed: + ----- Method: SMLoaderCategoricalPlus>>buildFancyWith: (in category 'DEPRECATED') ----- - ----- Method: SMLoaderCategoricalPlus>>buildFancyWith: (in category 'interface') ----- buildFancyWith: aBuilder "Creates a variant of the window where the package pane is split between installed and uninstalled packages." | buttonBarHeight searchHeight vertDivide horizDivide | buttonBarHeight := 0.07. searchHeight := 0.07. vertDivide := 0.5. horizDivide := 0.6. builder := aBuilder. window := builder build: (builder pluggableWindowSpec new model: self; label: #label; children: (OrderedCollection new add: ((self buildButtonBarWith: builder) frame: (0 @ 0 corner: 1 @ buttonBarHeight); yourself); add: ((self buildCategoriesListWith: builder) frame: (0 @ buttonBarHeight corner: vertDivide @ horizDivide); yourself); add: ((self buildSearchPaneWith: builder) frame: (vertDivide @ buttonBarHeight corner: 1 @ (buttonBarHeight + searchHeight)); yourself); add: ((self buildNotInstalledPackagesListWith: builder) frame: (vertDivide @ (buttonBarHeight + searchHeight) corner: 1 @ (horizDivide / 2)); yourself); add: ((self buildInstalledPackagesListWith: builder) frame: (vertDivide @ (horizDivide / 2) corner: 1 @ horizDivide); yourself); add: ((self buildPackagePaneWith: builder) frame: (0 @ horizDivide corner: 1 @ 1); yourself); yourself)). window on: #mouseEnter send: #paneTransition: to: window. window on: #mouseLeave send: #paneTransition: to: window. self setUpdatablePanesFrom: #(#installedPackageList #notInstalledPackageList ). currentPackageList := #notInstalled. window extent: self initialExtent. ^ window! Item was changed: + ----- Method: SMLoaderCategoricalPlus>>buildInstalledPackagesListWith: (in category 'DEPRECATED') ----- - ----- Method: SMLoaderCategoricalPlus>>buildInstalledPackagesListWith: (in category 'interface') ----- buildInstalledPackagesListWith: aBuilder ^ aBuilder pluggableTreeSpec new model: self; roots: #installedPackageList; getSelectedPath: #selectedItemPath; + getSelected: #selectedItem; setSelected: #selectedItem:; menu: #packagesMenu:; label: #itemLabel:; getChildren: #itemChildren:; hasChildren: #itemHasChildren:; autoDeselect: true; wantsDrop: true; yourself! Item was changed: + ----- Method: SMLoaderCategoricalPlus>>buildNotInstalledPackagesListWith: (in category 'DEPRECATED') ----- - ----- Method: SMLoaderCategoricalPlus>>buildNotInstalledPackagesListWith: (in category 'interface') ----- buildNotInstalledPackagesListWith: aBuilder ^ aBuilder pluggableTreeSpec new model: self; roots: #notInstalledPackageList; getSelectedPath: #selectedItemPath; + getSelected: #selectedItem; setSelected: #selectedItem:; menu: #packagesMenu:; label: #itemLabel:; getChildren: #itemChildren:; hasChildren: #itemHasChildren:; autoDeselect: true; wantsDrop: true; yourself! Item was changed: ----- Method: SMLoaderCategoricalPlus>>buildWith: (in category 'interface') ----- buildWith: aBuilder | buttonBarHeight searchHeight vertDivide horizDivide | + buttonBarHeight := Preferences standardButtonFont height * 2. + searchHeight := Preferences standardDefaultTextFont height * 2. - buttonBarHeight := 0.07. - searchHeight := 0.07. vertDivide := 0.5. horizDivide := 0.6. builder := aBuilder. window := builder build: (builder pluggableWindowSpec new model: self; label: #label; + children: (OrderedCollection new + add: ((self buildButtonBarWith: builder) + frame: (LayoutFrame + fractions: (0 @ 0 corner: 1 @ 0) + offsets: (0@0 corner: 0@buttonBarHeight))); + add: ((self buildCategoriesListWith: builder) + frame: (LayoutFrame + fractions: (0 @ 0 corner: vertDivide @ horizDivide) + offsets: (0@ buttonBarHeight corner: 0@0))); + add: ((self buildSearchPaneWith: builder) + frame: (LayoutFrame + fractions: (vertDivide @ 0 corner: 1 @ 0) + offsets: (0@ buttonBarHeight corner: 0@ (buttonBarHeight + searchHeight)))); + add: ((self buildPackagesListWith: builder) + frame: (LayoutFrame + fractions: (vertDivide @ 0 corner: 1 @ horizDivide) + offsets: (0 @ (buttonBarHeight + searchHeight) corner: 0@0))); + add: ((self buildPackagePaneWith: builder) + frame: (0 @ horizDivide corner: 1 @ 1)); + yourself); + yourself). - children: (OrderedCollection new add: - ((self buildButtonBarWith: builder) - frame: (0 @ 0 corner: 1 @ buttonBarHeight); yourself); - add: ((self buildCategoriesListWith: builder) - frame: (0 @ buttonBarHeight corner: vertDivide @ horizDivide); yourself); - add: ((self buildSearchPaneWith: builder) - frame: (vertDivide @ buttonBarHeight corner: 1 @ (buttonBarHeight + searchHeight))); - add: ((self buildPackagesListWith: builder) - frame: (vertDivide @ (buttonBarHeight + searchHeight) corner: 1 @ horizDivide)); - add: ((self buildPackagePaneWith: builder) - frame: (0 @ horizDivide corner: 1 @ 1)); yourself)). window on: #mouseEnter send: #paneTransition: to: window. window on: #mouseLeave send: #paneTransition: to: window. window extent: self initialExtent. ^ window! Item was changed: ----- Method: SMLoaderPlus>>buildCategoriesListWith: (in category 'interface') ----- buildCategoriesListWith: aBuilder "Create the hierarchical list holding the category tree." ^ aBuilder pluggableTreeSpec new model: self; roots: #categoryList; getSelectedPath: #selectedCategoryPath; getChildren: #categoryChildren:; hasChildren: #categoryHasChildren:; setSelected: #selectedCategory:; + getSelected: #selectedCategory; menu: #categoriesMenu:; label: #categoryLabel:; autoDeselect: true; wantsDrop: true; name: #categoriesList; yourself! Item was changed: ----- Method: SMLoaderPlus>>buildPackagePaneWith: (in category 'interface') ----- buildPackagePaneWith: aBuilder "Create the text area to the right in the loader." + ^ aBuilder pluggableTextSpec new + model: self; + getText: #itemDescription; + name: #packagePane; + help: 'Select a package to view its description.'; + yourself! - ^ aBuilder pluggableTextSpec new model: self; getText: #itemDescription; name: #packagePane; yourself! Item was changed: ----- Method: SMLoaderPlus>>buildPackagesListWith: (in category 'interface') ----- buildPackagesListWith: aBuilder "Create the hierarchical list holding the packages and releases." ^ aBuilder pluggableTreeSpec new model: self; roots: #packageList; getSelectedPath: #selectedItemPath; + getSelected: #selectedItem; setSelected: #selectedItem:; menu: #packagesMenu:; label: #itemLabel:; getChildren: #itemChildren:; hasChildren: #itemHasChildren:; autoDeselect: true; wantsDrop: true; name: #packagesList; yourself! Item was changed: ----- Method: SMLoaderPlus>>buildSearchPaneWith: (in category 'interface') ----- buildSearchPaneWith: aBuilder ^ aBuilder pluggableInputFieldSpec new model: self; selection: #searchSelection; + setText: #findPackage:notifying:; + help: 'Search packages...'; + name: #search; + yourself! - getText: #searchText; setText: #findPackage:notifying:; name: #search; yourself! Item was changed: ----- Method: SMLoaderPlus>>buildWith: (in category 'interface') ----- buildWith: aBuilder "Create the package loader window." + | buttonBarHeight searchPaneHeight vertDivide horizDivide | + buttonBarHeight := Preferences standardButtonFont height * 2. + searchPaneHeight := Preferences standardDefaultTextFont height * 2. - | buttonBarHeight vertDivide horizDivide | - buttonBarHeight := 0.07. vertDivide := 0.6. horizDivide := 0.3. builder := aBuilder. window := builder build: (builder pluggableWindowSpec new model: self; label: #label; children: (OrderedCollection new add: ((self buildButtonBarWith: builder) + frame: (LayoutFrame + fractions: (0 @ 0 corner: 1 @ 0) + offsets: (0@0 corner: 0@buttonBarHeight))); - frame: (0 @ 0 corner: 1 @ buttonBarHeight)); add: ((self buildSearchPaneWith: builder) + frame: (LayoutFrame + fractions: (0 @ 0 corner: horizDivide @ 0) + offsets: (0@ buttonBarHeight corner: 0@ (buttonBarHeight + searchPaneHeight)))); - frame: (0 @ buttonBarHeight corner: horizDivide @ (buttonBarHeight * 2))); add: ((self buildPackagesListWith: builder) + frame: (LayoutFrame + fractions: (0 @ 0 corner: horizDivide @ vertDivide) + offsets: (0 @ (buttonBarHeight + searchPaneHeight) corner: 0@0))); - frame: (0 @ (buttonBarHeight * 2) corner: horizDivide @ vertDivide)); add: ((self buildCategoriesListWith: builder) frame: (0 @ vertDivide corner: horizDivide @ 1)); add: ((self buildPackagePaneWith: builder) + frame: (LayoutFrame + fractions: (horizDivide @ 0 corner: 1 @ 1) + offsets: (0 @ buttonBarHeight corner: 0@0))); - frame: (horizDivide @ buttonBarHeight corner: 1 @ 1)); yourself); yourself). window on: #mouseEnter send: #paneTransition: to: window. window on: #mouseLeave send: #paneTransition: to: window. window extent: self initialExtent. ^ window! Item was changed: ----- Method: SMLoaderPlus>>itemDescription (in category 'private') ----- itemDescription ^ self selectedPackageOrRelease + ifNotNil: [:item | item fullDescription]! - ifNil: [''] - ifNotNilDo: [:item | item fullDescription]! Item was changed: ----- Method: SMLoaderPlus>>searchText (in category 'interface') ----- searchText "A dummy default search text so that the field describes its purpose." + ^ ''! - ^ 'Search packages'! Item was changed: ----- Method: SMLoaderPlus>>selectedCategory: (in category 'accessing') ----- selectedCategory: anSMCategory "Change the selected category." selectedCategory := anSMCategory. selectedCategory ifNotNil: [ (selectedCategory objects includes: self selectedItem) ifFalse: [ self selectedItem: nil ] ]. self + changed: #selectedCategory; - changed: #selectedCategoryPath ; changed: #packageList! Item was changed: ----- Method: SMLoaderPlus>>selectedItem: (in category 'accessing') ----- selectedItem: anItem "This == workaround protects us from recursion since ToolBuilder's tree widgets will always tell us that the selection has been updated when we tell it that the selection path has been updated. Cleaner solutions invited." anItem == selectedItem ifFalse: [ selectedItem := anItem. + self changed: #selectedItem. - self changed: #selectedItemPath. self changed: #itemDescription. self changed: #hasSelectedItem]! From commits at source.squeak.org Fri May 1 17:19:19 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 17:19:20 2015 Subject: [squeak-dev] The Trunk: Tools-mt.615.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.615.mcz ==================== Summary ==================== Name: Tools-mt.615 Author: mt Time: 1 May 2015, 7:19:00.098 pm UUID: d3a1a446-028b-e24f-8c15-084451b30c40 Ancestors: Tools-mt.614 Use code panes in inspector and object explorer (was text panes). =============== Diff against Tools-mt.614 =============== Item was changed: ----- Method: Inspector>>buildCodePaneWith: (in category 'toolbuilder') ----- buildCodePaneWith: builder | textSpec | + textSpec := builder pluggableCodePaneSpec new. - textSpec := builder pluggableTextSpec new. textSpec model: self; getText: #expression; editText: #expression:; help: #helpText; selection: #contentsSelection; menu: #codePaneMenu:shifted:; askBeforeDiscardingEdits: false. ^textSpec! Item was changed: ----- Method: ObjectExplorer>>buildWith: (in category 'toolbuilder') ----- buildWith: builder | windowSpec treeSpec textSpec buttonSpec buttonOffset | windowSpec := builder pluggableWindowSpec new. windowSpec model: self; children: OrderedCollection new; label: #label; extent: self initialExtent. treeSpec := builder pluggableTreeSpec new. treeSpec model: self; nodeClass: self class nodeClass; roots: #getList; keyPress: #explorerKey:from:event:; getSelected: #currentSelection; setSelected: #currentSelection:; setSelectedParent: #currentParent:; menu: #genericMenu:; autoDeselect: false; columns: (ObjectExplorerWrapper showContentsInColumns ifTrue: [{ [:listMorph | (listMorph filteredItems collect: [:item | item preferredWidthOfColumn: 1]) max]. nil "take all the space"}]); frame: (0@0 corner: 1@0.71). windowSpec children add: treeSpec. buttonOffset := (Preferences standardButtonFont widthOfString: 'inspect') * 3/2. + textSpec := builder pluggableCodePaneSpec new. - textSpec := builder pluggableTextSpec new. textSpec model: self; getText: #expression; editText: #expression:; menu: #codePaneMenu:shifted:; help: 'Evaluate expressions for the current tree selection...' translated; frame: (LayoutFrame fractions: (0@0.71 corner: 1@1) offsets: (0@0 corner: buttonOffset negated@0)). windowSpec children add: textSpec. buttonSpec := builder pluggableButtonSpec new model: self; label: 'inspect'; action: #inspectObject; help: 'Switch to an inspector tool'; frame: (LayoutFrame fractions: (1@0.71 corner: 1@1) offsets: (buttonOffset negated@0 corner: 0 @ 0)). windowSpec children add: buttonSpec. [^ builder build: windowSpec] ensure: [self changed: #expandRootsRequested]! From commits at source.squeak.org Fri May 1 18:00:30 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:00:32 2015 Subject: [squeak-dev] The Inbox: Multilingual-ul.209.mcz Message-ID: A new version of Multilingual was added to project The Inbox: http://source.squeak.org/inbox/Multilingual-ul.209.mcz ==================== Summary ==================== Name: Multilingual-ul.209 Author: ul Time: 1 May 2015, 7:48:22.654 pm UUID: 966caead-fd54-4687-9369-3580c258e5db Ancestors: Multilingual-ul.208 Refactored unicode data parsing. Case conversion (ToUpper and ToLower) is parsed from UnicodeData.txt instead of CaseFolding.txt. Reinitialize both CaseFolding and CompositionMapping in the postscript. =============== Diff against Multilingual-ul.206 =============== Item was added: + ----- Method: Unicode class>>caseFoldingData (in category 'casing') ----- + caseFoldingData + + UIManager default informUserDuring: [ :bar | + | stream | + bar value: 'Downloading CaseFolding Unicode data'. + stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/CaseFolding.txt'. + (stream isKindOf: RWBinaryOrTextStream) ifFalse: [ + ^self error: 'Download failed' ]. + ^stream reset; contents ]! Item was added: + ----- Method: Unicode class>>initializeCaseFolding (in category 'casing') ----- + initializeCaseFolding + " self initializeCaseFolding " + + self parseCaseFoldingFrom: self caseFoldingData! Item was removed: - ----- Method: Unicode class>>initializeCaseMappings (in category 'casing') ----- - initializeCaseMappings - "Unicode initializeCaseMappings" - ToCasefold := IdentityDictionary new. - ToUpper := IdentityDictionary new. - ToLower := IdentityDictionary new. - UIManager default informUserDuring: [:bar| - | stream | - bar value: 'Downloading Unicode data'. - stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/CaseFolding.txt'. - (stream isKindOf: RWBinaryOrTextStream) ifFalse:[^self error: 'Download failed']. - stream reset. - bar value: 'Updating Case Mappings'. - self parseCaseMappingFrom: stream. - ].! Item was changed: ----- Method: Unicode class>>initializeCompositionMappings (in category 'composing') ----- initializeCompositionMappings + " self initializeCompositionMappings " + + self parseCompositionMappingFrom: self unicodeData! - "Unicode initializeCompositionMappings" - Compositions := IdentityDictionary new. - Decompositions := IdentityDictionary new. - UIManager default informUserDuring:[:bar| - | stream | - bar value: 'Downloading Unicode data'. - stream := HTTPClient httpGet: 'http://unicode.org/Public/UNIDATA/UnicodeData.txt'. - (stream isKindOf: RWBinaryOrTextStream) ifFalse:[^self error: 'Download failed']. - stream reset. - bar value: 'Updating Composition Mappings'. - self parseCompositionMappingFrom: stream. - ].! Item was added: + ----- Method: Unicode class>>parseCaseFoldingFrom: (in category 'casing') ----- + parseCaseFoldingFrom: caseFoldingData + "Parse the Unicode casing mappings from the given string." + + | newToCasefold | + newToCasefold := PluggableDictionary integerDictionary. + + "Filter the mappings (Simple and Common) to newToCasefold." + caseFoldingData linesDo: [ :line | + | lineWithoutComment fields sourceCode destinationCode | + lineWithoutComment := line copyUpTo: $#. + fields := lineWithoutComment findTokens: '; '. + (fields size > 2 and: [ #('C' 'S') includes: (fields at: 2) ]) ifTrue: [ + sourceCode := Integer readFrom: (fields at: 1) base: 16. + destinationCode := Integer readFrom: (fields at: 3) base: 16. + newToCasefold at: sourceCode put: destinationCode ] ]. + + "Compact and save." + ToCasefold := newToCasefold compact + ! Item was removed: - ----- Method: Unicode class>>parseCaseMappingFrom: (in category 'casing') ----- - parseCaseMappingFrom: stream - "Parse the Unicode casing mappings from the given stream. - Handle only the simple mappings" - " - Unicode initializeCaseMappings. - " - - ToCasefold := IdentityDictionary new: 2048. - ToUpper := IdentityDictionary new: 2048. - ToLower := IdentityDictionary new: 2048. - - [stream atEnd] whileFalse:[ - | fields line srcCode dstCode | - line := stream nextLine copyUpTo: $#. - fields := line withBlanksTrimmed findTokens: $;. - (fields size > 2 and: [#('C' 'S') includes: (fields at: 2) withBlanksTrimmed]) ifTrue:[ - srcCode := Integer readFrom: (fields at: 1) withBlanksTrimmed base: 16. - dstCode := Integer readFrom: (fields at: 3) withBlanksTrimmed base: 16. - ToCasefold at: srcCode put: dstCode. - ]. - ]. - - ToCasefold keysAndValuesDo: - [:k :v | - (self isUppercaseCode: k) - ifTrue: - ["In most cases, uppercase letter are folded to lower case" - ToUpper at: v put: k. - ToLower at: k put: v]. - (self isLowercaseCode: k) - ifTrue: - ["In a few cases, two upper case letters are folded to the same lower case. - We must find an upper case letter folded to the same letter" - | up | - up := ToCasefold keys detect: [:e | (self isUppercaseCode: e) and: [(ToCasefold at: e) = v]] ifNone: [nil]. - up ifNotNil: [ToUpper at: k put: up]]].! Item was changed: ----- Method: Unicode class>>parseCompositionMappingFrom: (in category 'composing') ----- + parseCompositionMappingFrom: unicodeData - parseCompositionMappingFrom: stream "Parse the Unicode composition mappings from the given stream" " Unicode initializeCompositionMappings. " + | newCompositions newDecompositions newToUpper newToLower toNumber | - | toNumber fields codePoint decomposed baseChar compChar line | toNumber := [:quad | quad inject: 0 into:[:sum :ch| sum * 16 + ch digitValue]]. + newCompositions := PluggableDictionary integerDictionary. + newDecompositions := PluggableDictionary integerDictionary. + newToUpper := PluggableDictionary integerDictionary. + newToLower := PluggableDictionary integerDictionary. - Compositions := IdentityDictionary new: 2048. - Decompositions := IdentityDictionary new: 2048. + unicodeData linesDo: [ :line | + | fields | + (fields := line splitBy: ';') size > 13 ifTrue: [ + | codePoint lowercaseCodePoint uppercaseCodePoint decomposed baseChar compChar | - [stream atEnd] whileFalse:[ - line := (stream nextLine copyUpTo: $#) withBlanksTrimmed readStream. - fields := Array streamContents:[:s|[line atEnd] whileFalse:[s nextPut: (line upTo: $;)]]. - fields size > 6 ifTrue:[ codePoint := toNumber value: (fields at: 1). + uppercaseCodePoint := (fields at: 13) ifEmpty: [ codePoint ] ifNotEmpty: toNumber. + codePoint = uppercaseCodePoint ifFalse: [ newToUpper at: codePoint put: uppercaseCodePoint ]. + lowercaseCodePoint := (fields at: 14) ifEmpty: [ codePoint ] ifNotEmpty: toNumber. + codePoint = lowercaseCodePoint ifFalse: [ newToLower at: codePoint put: lowercaseCodePoint ]. decomposed := (fields at: 6) findTokens: ' '. (decomposed size = 2 and:[decomposed first first ~= $<]) ifTrue:[ + decomposed replace: toNumber. - decomposed := decomposed collect: toNumber. baseChar := decomposed first. "base character" compChar := decomposed second. "composition character" + newDecompositions at: codePoint put: { baseChar. compChar }. + (newCompositions at: baseChar ifAbsentPut: [ PluggableDictionary integerDictionary ]) + at: compChar put: codePoint ] ] ]. + + "Compact the new dictionaries." + newCompositions compact. + newCompositions valuesDo: [ :each | each compact ]. + newDecompositions compact. + newToUpper compact. + newToLower compact. + "Save atomically." + Compositions := newCompositions. + Decompositions := newDecompositions. + ToUpper := newToUpper. + ToLower := newToLower. - Decompositions at: codePoint put: (Array with: baseChar with: compChar). - (Compositions at: baseChar ifAbsentPut:[IdentityDictionary new]) - at: compChar put: codePoint. - ]. - ]. - ]. ! Item was added: + ----- Method: Unicode class>>unicodeData (in category 'composing') ----- + unicodeData + + UIManager default informUserDuring: [ :bar | + | stream | + bar value: 'Downloading Unicode data'. + stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/UnicodeData.txt'. + (stream isKindOf: RWBinaryOrTextStream) ifFalse: [ + ^self error: 'Download failed' ]. + ^stream reset; contents ]! Item was changed: + (PackageInfo named: 'Multilingual') postscript: 'Unicode + initializeCaseFolding; + initializeCompositionMappings'! - (PackageInfo named: 'Multilingual') postscript: '"Remove CrLfFileStream from the startupList" - (Smalltalk classNamed: ''CrLfFileStream'') ifNotNil: [ :class | - Smalltalk removeFromStartUpList: class ]. - "Ensure toLower et al work on WideStrings" - Unicode - initialize; - initializeCaseMappings. - '! From commits at source.squeak.org Fri May 1 18:00:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:00:45 2015 Subject: [squeak-dev] The Inbox: Multilingual-ul.208.mcz Message-ID: A new version of Multilingual was added to project The Inbox: http://source.squeak.org/inbox/Multilingual-ul.208.mcz ==================== Summary ==================== Name: Multilingual-ul.208 Author: ul Time: 1 May 2015, 3:25:18.828 pm UUID: 82d19dac-c602-4c0d-bc9a-7858e3a3c283 Ancestors: Multilingual-ul.206 Improved Unicode caseMappings: - Don't overwrite an existing mapping, because that leads to problems (like (Unicode toUppercaseCode: $k asciiValue) = 8490) - Use PluggableDictionary class >> #integerDictionary for better lookup performance (~+16%), and compaction resistance (done at every release). - Compact the dictionaries before saving. - Save the new dictionaries atomically. =============== Diff against Multilingual-ul.206 =============== Item was changed: ----- Method: Unicode class>>initializeCaseMappings (in category 'casing') ----- initializeCaseMappings "Unicode initializeCaseMappings" + + UIManager default informUserDuring: [ :bar | - ToCasefold := IdentityDictionary new. - ToUpper := IdentityDictionary new. - ToLower := IdentityDictionary new. - UIManager default informUserDuring: [:bar| | stream | bar value: 'Downloading Unicode data'. stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/CaseFolding.txt'. (stream isKindOf: RWBinaryOrTextStream) ifFalse:[^self error: 'Download failed']. stream reset. bar value: 'Updating Case Mappings'. + self parseCaseMappingFrom: stream ].! - self parseCaseMappingFrom: stream. - ].! Item was changed: ----- Method: Unicode class>>parseCaseMappingFrom: (in category 'casing') ----- parseCaseMappingFrom: stream "Parse the Unicode casing mappings from the given stream. Handle only the simple mappings" " Unicode initializeCaseMappings. " + | newToCasefold newToUpper newToLower casefoldKeys | + newToCasefold := PluggableDictionary integerDictionary. + newToUpper := PluggableDictionary integerDictionary. + newToLower := PluggableDictionary integerDictionary. - ToCasefold := IdentityDictionary new: 2048. - ToUpper := IdentityDictionary new: 2048. - ToLower := IdentityDictionary new: 2048. + "Filter the mappings (Simple and Common) to newToCasefold." + stream contents linesDo: [ :line | + | data fields sourceCode destinationCode | + data := line copyUpTo: $#. + fields := data findTokens: '; '. + (fields size > 2 and: [ #('C' 'S') includes: (fields at: 2) ]) ifTrue:[ + sourceCode := Integer readFrom: (fields at: 1) base: 16. + destinationCode := Integer readFrom: (fields at: 3) base: 16. + newToCasefold at: sourceCode put: destinationCode ] ]. - [stream atEnd] whileFalse:[ - | fields line srcCode dstCode | - line := stream nextLine copyUpTo: $#. - fields := line withBlanksTrimmed findTokens: $;. - (fields size > 2 and: [#('C' 'S') includes: (fields at: 2) withBlanksTrimmed]) ifTrue:[ - srcCode := Integer readFrom: (fields at: 1) withBlanksTrimmed base: 16. - dstCode := Integer readFrom: (fields at: 3) withBlanksTrimmed base: 16. - ToCasefold at: srcCode put: dstCode. - ]. - ]. + casefoldKeys := newToCasefold keys. + newToCasefold keysAndValuesDo: [ :sourceCode :destinationCode | + (self isUppercaseCode: sourceCode) ifTrue: [ + "In most cases, uppercase letter are folded to lower case" + newToUpper at: destinationCode put: sourceCode. + newToLower at: sourceCode ifAbsentPut: destinationCode "Don't overwrite existing pairs. To avoid $k asUppercase to return the Kelvin character (8490)." ]. + (self isLowercaseCode: sourceCode) ifTrue: [ + "In a few cases, two upper case letters are folded to the same lower case. + We must find an upper case letter folded to the same letter" + casefoldKeys + detect: [ :each | + (self isUppercaseCode: each) and: [ + (newToCasefold at: each) = destinationCode ] ] + ifFound: [ :uppercaseCode | + newToUpper at: sourceCode put: uppercaseCode ] + ifNone: [ ] ] ]. + + "Compact the dictionaries." + newToCasefold compact. + newToUpper compact. + newToLower compact. + "Save in an atomic operation." + ToCasefold := newToCasefold. + ToUpper := newToUpper. + ToLower := newToLower + ! - ToCasefold keysAndValuesDo: - [:k :v | - (self isUppercaseCode: k) - ifTrue: - ["In most cases, uppercase letter are folded to lower case" - ToUpper at: v put: k. - ToLower at: k put: v]. - (self isLowercaseCode: k) - ifTrue: - ["In a few cases, two upper case letters are folded to the same lower case. - We must find an upper case letter folded to the same letter" - | up | - up := ToCasefold keys detect: [:e | (self isUppercaseCode: e) and: [(ToCasefold at: e) = v]] ifNone: [nil]. - up ifNotNil: [ToUpper at: k put: up]]].! From commits at source.squeak.org Fri May 1 18:01:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:01:06 2015 Subject: [squeak-dev] The Inbox: Collections-ul.624.mcz Message-ID: A new version of Collections was added to project The Inbox: http://source.squeak.org/inbox/Collections-ul.624.mcz ==================== Summary ==================== Name: Collections-ul.624 Author: ul Time: 1 May 2015, 1:40:09.445 pm UUID: a89640e5-e0cc-44e1-9613-e065b78258ad Ancestors: Collections-tfel.623 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. =============== Diff against Collections-tfel.623 =============== Item was changed: Magnitude subclass: #Character instanceVariableNames: 'value' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + ClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + ClassificationTable at: code + 1 put: value ]! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + value < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | numArgs aStream offs |. - (numArgs := self numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Fri May 1 18:01:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:01:28 2015 Subject: [squeak-dev] The Inbox: Collections-ul.625.mcz Message-ID: A new version of Collections was added to project The Inbox: http://source.squeak.org/inbox/Collections-ul.625.mcz ==================== Summary ==================== Name: Collections-ul.625 Author: ul Time: 1 May 2015, 1:41:40.726 pm UUID: d09538cd-53f4-42d7-8070-224fde4a4ae2 Ancestors: Collections-ul.624 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. =============== Diff against Collections-ul.624 =============== Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + value > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: value)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + value > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: value)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! From commits at source.squeak.org Fri May 1 18:01:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:01:41 2015 Subject: [squeak-dev] The Trunk: ShoutCore-ul.46.mcz Message-ID: Levente Uzonyi uploaded a new version of ShoutCore to project The Trunk: http://source.squeak.org/trunk/ShoutCore-ul.46.mcz ==================== Summary ==================== Name: ShoutCore-ul.46 Author: ul Time: 26 April 2015, 8:28:25.9 pm UUID: d9c495e9-2e94-4c74-bc7c-8ff1448d0afd Ancestors: ShoutCore-ul.45 SHParserST80 performance improvements: - store the allowUnderscoreAssignments and allowUnderscoreSelectors preferences in instance variables - don't honor per class allowUnderscoreAssignments preferences anymore (just like how allowUnderscoreSelectors works) - ensure that instanceVariables is always an Array - reordered branches in some methods based on the methods of the Morph class as sample - use quick returns in frequently used testing methods - release the errorBlock in #parse, instead of an #ensure: block in #parse: - decreased the initial size of ranges to 40 - use Symbol >> #lookup: instead of Symbol >> #hasInterned:ifTrue: - use the fact that classOrMetaClass is nil when it's not a Behavior - use a fast primitive in #scanComment instead of a loop =============== Diff against ShoutCore-ul.45 =============== Item was changed: Object subclass: #SHParserST80 + instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment encodedCharSet allowUnderscoreAssignments allowUnderscoreSelectors' - instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment encodedCharSet' classVariableNames: '' poolDictionaries: '' category: 'ShoutCore-Parsing'! !SHParserST80 commentStamp: 'tween 8/16/2004 15:44' prior: 0! I am a Smalltalk method / expression parser. Rather than creating an Abstract Syntax Tree, I create a sequence of SHRanges (in my 'ranges' instance variable), which represent the tokens within the String I am parsing. I am used by a SHTextStylerST80 to parse method source strings. I am able to parse incomplete / incorrect methods, and so can be used to parse methods that are being edited. My 'source' instance variable should be set to the string to be parsed. My 'classOrMetaClass' instance var must be set to the class or metaClass for the method source so that I can correctly resolve identifiers within the source. If this is nil , I parse the source as an expression (i.e. a doIt expression). My 'workspace' instance variable can be set to a Workspace, so that I can resolve workspace variables. My 'environment' instance variable is the global namespace (this is initialized to Smalltalk, but can be set to a different environment). Example 1. ranges := SHParserST80 new classOrMetaClass: Object; source: 'testMethod ^self'; parse; ranges ! Item was removed: - ----- Method: SHParserST80>>allowUnderscoreAssignments (in category 'private') ----- - allowUnderscoreAssignments - "Query class + preference" - ^(classOrMetaClass ifNotNil: [:c | c allowUnderscoreAssignments]) - ifNil: [Scanner allowUnderscoreAsAssignment ]! Item was removed: - ----- Method: SHParserST80>>allowUnderscoreSelectors (in category 'private') ----- - allowUnderscoreSelectors - ^ Scanner prefAllowUnderscoreSelectors! Item was changed: ----- Method: SHParserST80>>initializeInstanceVariables (in category 'parse support') ----- initializeInstanceVariables + + instanceVariables := classOrMetaClass + ifNil: [ #() ] + ifNotNil: [ classOrMetaClass allInstVarNames asArray ]! - instanceVariables := classOrMetaClass notNil - ifTrue: [classOrMetaClass allInstVarNames asArray] - ifFalse: [Set new]! Item was changed: ----- Method: SHParserST80>>isAssignment (in category 'token testing') ----- isAssignment + + self isAnsiAssignment ifTrue: [ ^true ]. + ^allowUnderscoreAssignments and: [ currentToken = '_' ]! - ^self isAnsiAssignment or: [self allowUnderscoreAssignments and: [currentToken = '_']]! Item was changed: ----- Method: SHParserST80>>isBinary (in category 'token testing') ----- isBinary + + currentToken ifNil: [ ^false ]. + self isName ifTrue: [ ^false ]. + self isKeyword ifTrue: [ ^false ]. + 1 to: currentToken size do: [ :i | + (self isSelectorCharacter: (currentToken at: i)) ifFalse: [ ^false ] ]. - (currentToken isNil or: [self isName or: [self isKeyword]]) - ifTrue: [^false]. - 1 to: currentToken size do: [:i | | c | - c := currentToken at: i. - (self isSelectorCharacter: c) - ifFalse: [^false]]. ^true! Item was changed: ----- Method: SHParserST80>>isKeyword (in category 'token testing') ----- isKeyword "This method assumes that currentTokenFirst is a non-letter character when currentToken is nil." + (encodedCharSet isLetter: currentTokenFirst) ifTrue: [ + ^currentToken last == $: ]. + ^allowUnderscoreSelectors + and: [ currentTokenFirst == $_ + and: [ currentToken notNil + and: [ currentToken size > 1 + and: [ currentToken last == $: ] ] ] ]! - ^((encodedCharSet isLetter: currentTokenFirst) or: [ - currentTokenFirst == $_ and: [ - currentToken notNil and: [ - currentToken size > 1 and: [ - self allowUnderscoreSelectors ] ] ] ]) and: [ - currentToken last == $: ]! Item was changed: ----- Method: SHParserST80>>isName (in category 'token testing') ----- isName "This method assumes that currentTokenFirst is a non-letter character when currentToken is nil." ^((encodedCharSet isLetter: currentTokenFirst) + or: [ allowUnderscoreSelectors + and: [ currentTokenFirst == $_ - or: [ currentTokenFirst == $_ and: [ currentToken notNil + and: [ currentToken size > 1 ] ] ] ]) - and: [ currentToken size > 1 - and: [ self allowUnderscoreSelectors ] ] ] ]) and: [ (encodedCharSet isAlphaNumeric: currentToken last) + or: [ allowUnderscoreSelectors + and: [ currentToken last == $_ ] ] ] ! - or: [ currentToken last == $_ - and: [ self allowUnderscoreSelectors ] ] ] ! Item was changed: ----- Method: SHParserST80>>isSelectorCharacter: (in category 'character testing') ----- isSelectorCharacter: aCharacter + | asciiValue | + ('"#$'':().;[]{}^_' includes: aCharacter) ifTrue: [ ^false ]. + aCharacter isSeparator ifTrue:[ ^false ]. + (encodedCharSet isAlphaNumeric: aCharacter) ifTrue: [ ^false ]. + (asciiValue := aCharacter asciiValue) = 30 ifTrue: [ ^false "the doIt char" ]. + ^asciiValue ~= 0 "Any other char, but 0 is ok as a binary selector char." - (encodedCharSet isAlphaNumeric: aCharacter) ifTrue: [^false]. - aCharacter isSeparator ifTrue:[^false]. - ('"#$'':().;[]{}^_' includes: aCharacter) - ifTrue:[^false]. - aCharacter asciiValue = 30 ifTrue: [^false "the doIt char"]. - aCharacter asciiValue = 0 ifTrue: [^false]. - "Any other char is ok as a binary selector char." - ^true ! Item was changed: ----- Method: SHParserST80>>nextChar (in category 'scan') ----- nextChar + + ^source at: (sourcePosition := sourcePosition + 1) ifAbsent: $ ! - sourcePosition := sourcePosition + 1. - ^source at: sourcePosition ifAbsent: $ ! Item was changed: ----- Method: SHParserST80>>parse (in category 'parse') ----- parse + "Parse the receiver's text as a Smalltalk method" - "Parse the receiver's text as a Smalltalk method" + self parse: classOrMetaClass notNil. + errorBlock := nil! - ^self parse: (classOrMetaClass notNil) ! Item was changed: ----- Method: SHParserST80>>parse: (in category 'parse') ----- parse: isAMethod "Parse the receiver's text. If isAMethod is true then treat text as a method, if false as an expression with no message pattern" self initializeInstanceVariables. + allowUnderscoreAssignments := Scanner allowUnderscoreAsAssignment. + allowUnderscoreSelectors := Scanner prefAllowUnderscoreSelectors. sourcePosition := 1. arguments := Dictionary new. temporaries := Dictionary new. blockDepth := bracketDepth := 0. ranges + ifNil: [ ranges := OrderedCollection new: 40 "Covers over 80% of all methods." ] + ifNotNil: [ ranges reset ]. - ifNil: [ranges := OrderedCollection new: 100] - ifNotNil: [ranges reset]. errorBlock := [^false]. + self scanNext. + isAMethod ifTrue: [ + self + parseMessagePattern; + parsePragmaSequence ]. - [self scanNext. - isAMethod - ifTrue: [ - self parseMessagePattern. - self parsePragmaSequence]. self parseMethodTemporaries. + isAMethod ifTrue: [ self parsePragmaSequence ]. - isAMethod ifTrue: [self parsePragmaSequence]. self parseStatementList. + currentToken ifNotNil: [ self error ]. - currentToken ifNotNil: [self error]] - ensure:[errorBlock := nil]. ^true! Item was changed: ----- Method: SHParserST80>>parseSymbol (in category 'parse') ----- parseSymbol | c | currentToken = '#' ifTrue: [ "if token is just the #, then scan whitespace and comments and then process the next character. Squeak allows space between the # and the start of the symbol e.g. # (), # a, # 'sym' " self rangeType: #symbol. self scanWhitespace]. c := self currentChar. self failWhen: (c isNil or: [c isSeparator]). c == $( ifTrue: [ self nextChar. self scanPast: #arrayStart start: currentTokenSourcePosition end: currentTokenSourcePosition + 1. ^self parseArray]. c == $' ifTrue: [^self parseSymbolString]. c == $[ ifTrue: [ self nextChar. self scanPast: #byteArrayStart start: currentTokenSourcePosition end: currentTokenSourcePosition + 1. ^self parseByteArray]. ((self isSelectorCharacter: c) or: [c == $-]) ifTrue: [^self parseSymbolSelector]. + ((encodedCharSet isLetter: c) + or: [ c == $: + or: [ allowUnderscoreSelectors and: [ c == $_ ] ] ]) - ((encodedCharSet isLetter: c) or: [ - c == $: or: [ - c == $_ and: [self allowUnderscoreSelectors] ] ]) ifTrue: [^self parseSymbolIdentifier]. ^self parseCharSymbol! Item was changed: ----- Method: SHParserST80>>parseSymbolIdentifier (in category 'parse') ----- parseSymbolIdentifier + | c start end | c := self currentChar. + self failUnless: ( + (encodedCharSet isLetter: c) + or: [ c == $: + or: [ allowUnderscoreSelectors and: [ c == $_ ] ] ]). - self failUnless: ((encodedCharSet isLetter: c) or: [c == $: or: [c == $_ and: [self allowUnderscoreSelectors]]]). start := sourcePosition. + [ + c := self nextChar. + (encodedCharSet isAlphaNumeric: c) + or: [ c == $: + or: [ allowUnderscoreSelectors and: [ c == $_] ] ] ] whileTrue. - [c := self nextChar. - (encodedCharSet isAlphaNumeric: c) or: [c == $: or: [c == $_ and: [self allowUnderscoreSelectors]]]] whileTrue. end := sourcePosition - 1. c := source copyFrom: start - 1 to: end. self scanPast: #symbol start: start - 1 end: end. ^c! Item was changed: ----- Method: SHParserST80>>peekChar (in category 'scan') ----- peekChar + ^source at: sourcePosition + 1 ifAbsent: $ ! Item was changed: ----- Method: SHParserST80>>pushTemporary: (in category 'parse support') ----- + pushTemporary: aString + + (temporaries at: blockDepth ifAbsentPut: [ OrderedCollection new ]) - pushTemporary: aString - (temporaries at: blockDepth ifAbsentPut: [OrderedCollection new: 10]) add: aString! Item was changed: ----- Method: SHParserST80>>resolve: (in category 'identifier testing') ----- resolve: aString aString = #self ifTrue: [ ^#self ]. aString = #true ifTrue: [ ^#true ]. aString = #false ifTrue: [ ^#false ]. aString = #nil ifTrue: [ ^#nil ]. aString = #super ifTrue: [ ^#super ]. aString = #thisContext ifTrue: [ ^#thisContext ]. (self isBlockTempName: aString) ifTrue: [^#blockTempVar]. (self isBlockArgName: aString) ifTrue: [^#blockArg]. (self isMethodTempName: aString) ifTrue: [^#tempVar]. (self isMethodArgName: aString) ifTrue: [^#methodArg]. (instanceVariables includes: aString) ifTrue: [^#instVar]. workspace ifNotNil: [(workspace hasBindingOf: aString) ifTrue: [^#workspaceVar]]. + (Symbol lookup: aString) ifNotNil: [:sym | + classOrMetaClass + ifNotNil: [ + classOrMetaClass theNonMetaClass withAllSuperclassesDo: [:c | - Symbol hasInterned: aString ifTrue: [:sym | - classOrMetaClass isBehavior - ifTrue: [ - classOrMetaClass theNonMetaClass withAllSuperclasses do: [:c | (c classPool bindingOf: sym) ifNotNil: [^#classVar]. c sharedPools do: [:p | (p bindingOf: sym) ifNotNil: [^#poolConstant]]. (c environment bindingOf: sym) ifNotNil: [^#globalVar]]] + ifNil: [(environment bindingOf: sym) ifNotNil: [^#globalVar]]]. - ifFalse: [(environment bindingOf: sym) ifNotNil: [^#globalVar]]]. ^self resolvePartial: aString! Item was changed: ----- Method: SHParserST80>>resolvePartial: (in category 'identifier testing') ----- resolvePartial: aString "check if any identifier begins with aString" (#('self' 'super' 'true' 'false' 'nil' 'thisContext') anySatisfy: [:each | each beginsWith: aString]) ifTrue: [^#incompleteIdentifier]. (self isIncompleteBlockTempName: aString) ifTrue: [^#incompleteIdentifier]. (self isIncompleteBlockArgName: aString) ifTrue: [^#incompleteIdentifier]. (self isIncompleteMethodTempName: aString) ifTrue: [^#incompleteIdentifier]. (self isIncompleteMethodArgName: aString) ifTrue: [^#incompleteIdentifier]. (instanceVariables anySatisfy: [:each | each beginsWith: aString]) ifTrue: [^#incompleteIdentifier]. workspace ifNotNil: [(workspace hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. + classOrMetaClass + ifNotNil: [ - classOrMetaClass isBehavior - ifTrue: [ classOrMetaClass theNonMetaClass withAllSuperclasses do: [:c | (c classPool hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]. c sharedPools do: [:p | (p hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. (c environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]] + ifNil: [(environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. - ifFalse: [(environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. ^#undefinedIdentifier! Item was changed: ----- Method: SHParserST80>>resolvePartialPragmaArgument: (in category 'identifier testing') ----- resolvePartialPragmaArgument: aString "check if any valid pragma argument begins with aString" (#('true' 'false' 'nil') anySatisfy: [:each | each beginsWith: aString]) ifTrue: [^#incompleteIdentifier]. "should really check that a matching binding is for a Class?" + classOrMetaClass + ifNotNil: [ - classOrMetaClass isBehavior - ifTrue: [ classOrMetaClass theNonMetaClass withAllSuperclasses do: [:c | (c environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]] + ifNil: [(environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. - ifFalse: [(environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. ^#undefinedIdentifier! Item was changed: ----- Method: SHParserST80>>resolvePragmaArgument: (in category 'identifier testing') ----- resolvePragmaArgument: aString (#('true' 'false' 'nil') includes: aString) ifTrue: [^aString asSymbol]. "should really check that global is a class?" + (Symbol lookup: aString) ifNotNil: [:sym | + classOrMetaClass + ifNotNil: [ - Symbol hasInterned: aString ifTrue: [:sym | - classOrMetaClass isBehavior - ifTrue: [ classOrMetaClass theNonMetaClass withAllSuperclasses do: [:c | (c environment bindingOf: sym) ifNotNil: [^#globalVar]]] + ifNil: [(environment bindingOf: sym) ifNotNil: [^#globalVar]]]. - ifFalse: [(environment bindingOf: sym) ifNotNil: [^#globalVar]]]. ^self resolvePartialPragmaArgument: aString! Item was changed: ----- Method: SHParserST80>>scanComment (in category 'scan') ----- scanComment + + | start | + start := sourcePosition. + (sourcePosition := source indexOf: $" startingAt: start + 1) = 0 ifTrue: [ + sourcePosition := source size + 1. + self rangeType: #unfinishedComment start: start end: source size. + ^self error ]. + start < sourcePosition ifTrue: [ + self rangeType: #comment start: start end: sourcePosition ]. + self + nextChar; + scanWhitespace! - | c s e | - s := sourcePosition. - - [sourcePosition := sourcePosition + 1. - (c := self currentChar) - ifNil: [ - self rangeType: #unfinishedComment start: s end: source size. - ^self error ": 'unfinished comment'"]. - c == $"] - whileFalse: []. - e := sourcePosition. - s < e ifTrue: [self rangeType: #comment start: s end: e]. - self nextChar. - self scanWhitespace! Item was changed: ----- Method: SHParserST80>>scanIdentifier (in category 'scan') ----- scanIdentifier + | c start | start := sourcePosition. + [ + (encodedCharSet isAlphaNumeric: (c := self nextChar)) + or: [ allowUnderscoreSelectors and: [ c == $_ ] ] ] whileTrue. + (c == $: and: [ (self isSelectorCharacter: self peekChar) not ]) + ifTrue: [ self nextChar ]. - [(encodedCharSet isAlphaNumeric: (c := self nextChar)) or: [c == $_ and: [self allowUnderscoreSelectors]]] whileTrue. - (c == $: and: [(self isSelectorCharacter: self peekChar) not]) - ifTrue: [self nextChar]. currentToken := source copyFrom: start to: sourcePosition - 1. currentTokenSourcePosition := start! Item was changed: ----- Method: SHParserST80>>scanNext (in category 'scan') ----- scanNext + self scanWhitespace. + currentTokenFirst := self currentChar ifNil: [ + " end of input " + currentTokenFirst := $ . + currentTokenSourcePosition := nil. + currentToken := nil. + ^nil ]. + (encodedCharSet isDigit: currentTokenFirst) ifTrue: [ ^self scanNumber ]. - currentTokenFirst := self currentChar. - currentTokenFirst - ifNil: [" end of input " - currentTokenFirst := $ . - currentTokenSourcePosition := nil. - currentToken := nil. - ^nil]. - (encodedCharSet isDigit: currentTokenFirst) ifTrue: [^self scanNumber]. ((encodedCharSet isLetter: currentTokenFirst) or: [ + allowUnderscoreSelectors and: [ currentTokenFirst == $_ ] ]) + ifTrue: [ ^self scanIdentifier ]. - currentTokenFirst == $_ and: [ self allowUnderscoreSelectors ] ]) - ifTrue: [^self scanIdentifier]. ^self scanBinary! From commits at source.squeak.org Fri May 1 18:01:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:01:59 2015 Subject: [squeak-dev] The Trunk: ShoutCore-ul.47.mcz Message-ID: Levente Uzonyi uploaded a new version of ShoutCore to project The Trunk: http://source.squeak.org/trunk/ShoutCore-ul.47.mcz ==================== Summary ==================== Name: ShoutCore-ul.47 Author: ul Time: 1 May 2015, 1:52:05.9 pm UUID: a4a03a3c-da8f-4e81-86f5-09b950cfeabe Ancestors: ShoutCore-ul.46 Removed encodedCharSet from SHParserST80. All methods referencing it are sending the corresponding method to the character again. =============== Diff against ShoutCore-ul.46 =============== Item was changed: Object subclass: #SHParserST80 + instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment allowUnderscoreAssignments allowUnderscoreSelectors' - instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment encodedCharSet allowUnderscoreAssignments allowUnderscoreSelectors' classVariableNames: '' poolDictionaries: '' category: 'ShoutCore-Parsing'! !SHParserST80 commentStamp: 'tween 8/16/2004 15:44' prior: 0! I am a Smalltalk method / expression parser. Rather than creating an Abstract Syntax Tree, I create a sequence of SHRanges (in my 'ranges' instance variable), which represent the tokens within the String I am parsing. I am used by a SHTextStylerST80 to parse method source strings. I am able to parse incomplete / incorrect methods, and so can be used to parse methods that are being edited. My 'source' instance variable should be set to the string to be parsed. My 'classOrMetaClass' instance var must be set to the class or metaClass for the method source so that I can correctly resolve identifiers within the source. If this is nil , I parse the source as an expression (i.e. a doIt expression). My 'workspace' instance variable can be set to a Workspace, so that I can resolve workspace variables. My 'environment' instance variable is the global namespace (this is initialized to Smalltalk, but can be set to a different environment). Example 1. ranges := SHParserST80 new classOrMetaClass: Object; source: 'testMethod ^self'; parse; ranges ! Item was changed: ----- Method: SHParserST80>>isKeyword (in category 'token testing') ----- isKeyword "This method assumes that currentTokenFirst is a non-letter character when currentToken is nil." + currentTokenFirst isLetter ifTrue: [ - (encodedCharSet isLetter: currentTokenFirst) ifTrue: [ ^currentToken last == $: ]. ^allowUnderscoreSelectors and: [ currentTokenFirst == $_ and: [ currentToken notNil and: [ currentToken size > 1 and: [ currentToken last == $: ] ] ] ]! Item was changed: ----- Method: SHParserST80>>isName (in category 'token testing') ----- isName "This method assumes that currentTokenFirst is a non-letter character when currentToken is nil." + ^(currentTokenFirst isLetter - ^((encodedCharSet isLetter: currentTokenFirst) or: [ allowUnderscoreSelectors and: [ currentTokenFirst == $_ and: [ currentToken notNil and: [ currentToken size > 1 ] ] ] ]) + and: [ currentToken last isAlphaNumeric - and: [ (encodedCharSet isAlphaNumeric: currentToken last) or: [ allowUnderscoreSelectors and: [ currentToken last == $_ ] ] ] ! Item was changed: ----- Method: SHParserST80>>isSelectorCharacter: (in category 'character testing') ----- isSelectorCharacter: aCharacter | asciiValue | ('"#$'':().;[]{}^_' includes: aCharacter) ifTrue: [ ^false ]. aCharacter isSeparator ifTrue:[ ^false ]. + aCharacter isAlphaNumeric ifTrue: [ ^false ]. - (encodedCharSet isAlphaNumeric: aCharacter) ifTrue: [ ^false ]. (asciiValue := aCharacter asciiValue) = 30 ifTrue: [ ^false "the doIt char" ]. ^asciiValue ~= 0 "Any other char, but 0 is ok as a binary selector char." ! Item was changed: ----- Method: SHParserST80>>parseByteArray (in category 'parse') ----- parseByteArray + [currentTokenFirst == $]] whileFalse: [ + currentTokenFirst isDigit - (encodedCharSet isDigit: currentTokenFirst) ifTrue: [ "do not parse the number, can be time consuming" self scanPast: #number] ifFalse: [ self failWhen: currentTokenFirst == $. . self error]]. self scanPast: #byteArrayEnd! Item was changed: ----- Method: SHParserST80>>parseExternalCall (in category 'parse') ----- parseExternalCall [self scanNext. ((Smalltalk at: #ExternalFunction) callingConventionModifierFor: currentToken) notNil] whileTrue. self failUnless: currentToken notNil. self scanPast: #externalCallType. currentToken = '*' ifTrue: [self scanPast: #externalCallTypePointerIndicator]. + currentTokenFirst isDigit - (encodedCharSet isDigit: currentTokenFirst) ifTrue: [self scanPast: #integer] ifFalse: [ self failUnless: currentTokenFirst == $'. self parseString]. self failUnless: currentTokenFirst == $(. self scanPast: #leftParenthesis. [currentTokenFirst ~= $)] whileTrue: [ self failUnless: currentToken notNil. self scanPast: #externalCallType. currentToken = '*' ifTrue: [self scanPast: #externalCallTypePointerIndicator]]. self scanPast: #rightParenthesis. currentToken = 'module:' ifTrue: [ self scanPast: #module. self parseStringOrSymbol ]. currentToken = 'error:' ifTrue: [ self scanPast: #primitive. "there's no rangeType for error" self isName ifTrue: [ self scanPast: #patternTempVar ] ifFalse: [ self parseStringOrSymbol ] ]. self failUnless: currentToken = '>'. self scanPast: #primitiveOrExternalCallEnd! Item was changed: ----- Method: SHParserST80>>parseLiteral: (in category 'parse') ----- + parseLiteral: inArray + - parseLiteral: inArray currentTokenFirst == $$ ifTrue: [ | pos | self failWhen: self currentChar isNil. self rangeType: #'$'. pos := currentTokenSourcePosition + 1. self nextChar. ^self scanPast: #character start: pos end: pos]. + currentTokenFirst isDigit - (encodedCharSet isDigit: currentTokenFirst) ifTrue: [ "do not parse the number, can be time consuming" ^self scanPast: #number]. currentToken = '-' ifTrue: [ | c | c := self currentChar. + (inArray and: [c isNil or: [ c isDigit not ]]) - (inArray and: [c isNil or: [(encodedCharSet isDigit: c) not]]) ifTrue: [ "single - can be a symbol in an Array" ^self scanPast: #symbol]. self scanPast: #-. self failWhen: currentToken isNil. "token isNil ifTrue: [self error: 'Unexpected End Of Input']." "do not parse the number, can be time consuming" ^self scanPast: #number]. currentTokenFirst == $' ifTrue: [^self parseString]. currentTokenFirst == $# ifTrue: [^self parseSymbol]. (inArray and: [currentToken notNil]) ifTrue: [^self scanPast: #symbol]. self failWhen: currentTokenFirst == $. . self error ": 'argument missing'"! Item was changed: ----- Method: SHParserST80>>parseLiteralArrayElement (in category 'parse') ----- parseLiteralArrayElement + + currentTokenFirst isLetter ifTrue: [ + #true = currentToken ifTrue: [ ^self scanPast: #true ]. + #false = currentToken ifTrue: [ ^self scanPast: #false ]. + #nil = currentToken ifTrue: [ ^self scanPast: #nil ]. + ^self scanPast: #symbol ]. + currentTokenFirst == $( ifTrue: [ + self scanPast: #arrayStart. + ^self parseArray ]. - (encodedCharSet isLetter: currentTokenFirst) - ifTrue: [ - #true = currentToken ifTrue: [ ^self scanPast: #true ]. - #false = currentToken ifTrue: [ ^self scanPast: #false ]. - #nil = currentToken ifTrue: [ ^self scanPast: #nil ]. - ^self scanPast: #symbol ]. - currentTokenFirst == $( - ifTrue: [ - self scanPast: #arrayStart. - ^self parseArray]. ^self parseLiteral: true! Item was changed: ----- Method: SHParserST80>>parsePrimitive (in category 'parse') ----- parsePrimitive self scanNext. + currentTokenFirst isDigit - (encodedCharSet isDigit: currentTokenFirst) ifTrue: [ self scanPast: #integer ] ifFalse: [ self parseStringOrSymbol. currentToken = 'module:' ifTrue: [ self scanPast: #module. self parseStringOrSymbol ] ]. currentToken = 'error:' ifTrue: [ self scanPast: #primitive. "there's no rangeType for error" self isName ifTrue: [ self scanPast: #patternTempVar ] ifFalse: [ self parseStringOrSymbol ] ]. self failUnless: currentToken = '>'. self scanPast: #primitiveOrExternalCallEnd! Item was changed: ----- Method: SHParserST80>>parseSymbol (in category 'parse') ----- parseSymbol | c | currentToken = '#' ifTrue: [ "if token is just the #, then scan whitespace and comments and then process the next character. Squeak allows space between the # and the start of the symbol e.g. # (), # a, # 'sym' " self rangeType: #symbol. self scanWhitespace]. c := self currentChar. self failWhen: (c isNil or: [c isSeparator]). c == $( ifTrue: [ self nextChar. self scanPast: #arrayStart start: currentTokenSourcePosition end: currentTokenSourcePosition + 1. ^self parseArray]. c == $' ifTrue: [^self parseSymbolString]. c == $[ ifTrue: [ self nextChar. self scanPast: #byteArrayStart start: currentTokenSourcePosition end: currentTokenSourcePosition + 1. ^self parseByteArray]. ((self isSelectorCharacter: c) or: [c == $-]) ifTrue: [^self parseSymbolSelector]. + (c isLetter - ((encodedCharSet isLetter: c) or: [ c == $: or: [ allowUnderscoreSelectors and: [ c == $_ ] ] ]) ifTrue: [^self parseSymbolIdentifier]. ^self parseCharSymbol! Item was changed: ----- Method: SHParserST80>>parseSymbolIdentifier (in category 'parse') ----- parseSymbolIdentifier | c start end | c := self currentChar. self failUnless: ( + c isLetter - (encodedCharSet isLetter: c) or: [ c == $: or: [ allowUnderscoreSelectors and: [ c == $_ ] ] ]). start := sourcePosition. [ + (c := self nextChar) isAlphaNumeric - c := self nextChar. - (encodedCharSet isAlphaNumeric: c) or: [ c == $: + or: [ allowUnderscoreSelectors and: [ c == $_ ] ] ] ] whileTrue. - or: [ allowUnderscoreSelectors and: [ c == $_] ] ] ] whileTrue. end := sourcePosition - 1. c := source copyFrom: start - 1 to: end. self scanPast: #symbol start: start - 1 end: end. ^c! Item was changed: ----- Method: SHParserST80>>scanIdentifier (in category 'scan') ----- scanIdentifier | c start | start := sourcePosition. [ + (c := self nextChar) isAlphaNumeric - (encodedCharSet isAlphaNumeric: (c := self nextChar)) or: [ allowUnderscoreSelectors and: [ c == $_ ] ] ] whileTrue. (c == $: and: [ (self isSelectorCharacter: self peekChar) not ]) ifTrue: [ self nextChar ]. currentToken := source copyFrom: start to: sourcePosition - 1. currentTokenSourcePosition := start! Item was changed: ----- Method: SHParserST80>>scanNext (in category 'scan') ----- scanNext self scanWhitespace. currentTokenFirst := self currentChar ifNil: [ " end of input " currentTokenFirst := $ . currentTokenSourcePosition := nil. currentToken := nil. ^nil ]. + currentTokenFirst isDigit ifTrue: [ ^self scanNumber ]. + (currentTokenFirst isLetter or: [ - (encodedCharSet isDigit: currentTokenFirst) ifTrue: [ ^self scanNumber ]. - ((encodedCharSet isLetter: currentTokenFirst) or: [ allowUnderscoreSelectors and: [ currentTokenFirst == $_ ] ]) ifTrue: [ ^self scanIdentifier ]. ^self scanBinary! Item was changed: ----- Method: SHParserST80>>scanNumber (in category 'scan') ----- scanNumber | start c nc base | start := sourcePosition. self skipDigits. c := self currentChar. c == $r ifTrue: [ base := Integer readFrom: (ReadStream on: (source copyFrom: start to: sourcePosition - 1)). self peekChar == $- ifTrue:[self nextChar]. self skipBigDigits: base. c := self currentChar. c == $. ifTrue: [ (self isBigDigit: self nextChar base: base) ifFalse: [sourcePosition := sourcePosition - 1] ifTrue: [self skipBigDigits: base]]. c := self currentChar. ('deq'includes: c) ifTrue: [ + ((nc := self nextChar) isDigit or: [nc == $- and: [ self peekChar isDigit ]]) - ((encodedCharSet isDigit: (nc := self nextChar)) or: [nc == $- and:[(encodedCharSet isDigit: self peekChar)]]) ifFalse: [sourcePosition := sourcePosition - 1] ifTrue: [self skipDigits]]. c == $s ifTrue: [ + (nc := self nextChar) isDigit - (encodedCharSet isDigit: (nc := self nextChar)) ifTrue: [ self skipDigits ] ifFalse: [ + nc isLetter ifTrue: [ - (encodedCharSet isLetter: nc) ifTrue: [ sourcePosition := sourcePosition - 1 ] ] ]. currentToken := source copyFrom: start to: sourcePosition - 1. ^currentTokenSourcePosition := start]. c == $s ifTrue: [ + (nc := self nextChar) isDigit - (encodedCharSet isDigit: (nc := self nextChar)) ifFalse: [nc isLetter ifTrue: [sourcePosition := sourcePosition - 1]] ifTrue: [self skipDigits.]. currentToken := source copyFrom: start to: sourcePosition - 1. ^currentTokenSourcePosition := start]. c == $. ifTrue: [ + self nextChar isDigit - (encodedCharSet isDigit: self nextChar) ifFalse: [ sourcePosition := sourcePosition - 1. currentToken := source copyFrom: start to: sourcePosition - 1. ^currentTokenSourcePosition := start] ifTrue: [self skipDigits]]. c := self currentChar. ('deq' includes: c) ifTrue: [ + ((nc := self nextChar) isDigit or: [nc == $- and:[ self peekChar isDigit ]]) - ((encodedCharSet isDigit: (nc := self nextChar)) or: [nc == $- and:[(encodedCharSet isDigit: self peekChar)]]) ifFalse: [sourcePosition := sourcePosition - 1] ifTrue: [self skipDigits]]. c == $s ifTrue: [ + (nc := self nextChar) isDigit - (encodedCharSet isDigit: (nc := self nextChar)) ifFalse: [nc isLetter ifTrue: [sourcePosition := sourcePosition - 1]] ifTrue: [self skipDigits]]. currentToken := source copyFrom: start to: sourcePosition - 1. ^currentTokenSourcePosition := start! Item was changed: ----- Method: SHParserST80>>skipDigits (in category 'scan') ----- skipDigits + [ self nextChar isDigit ] whileTrue! - [ (encodedCharSet isDigit: self nextChar) ] whileTrue! Item was changed: ----- Method: SHParserST80>>source: (in category 'accessing') ----- source: aString + source := aString - source := aString. - encodedCharSet := (source at: 1 ifAbsent: [ $0 ]) encodedCharSet ! From commits at source.squeak.org Fri May 1 18:10:45 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:10:47 2015 Subject: [squeak-dev] The Trunk: Collections-mt.626.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.626.mcz ==================== Summary ==================== Name: Collections-mt.626 Author: mt Time: 1 May 2015, 8:10:29.695 pm UUID: e8f27fe3-f480-8244-92bb-a23d8f61fd20 Ancestors: Collections-mt.625 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. =============== Diff against Collections-mt.625 =============== Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! From marcel.taeumel at student.hpi.uni-potsdam.de Fri May 1 17:57:51 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Fri May 1 18:13:05 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.626.mcz In-Reply-To: References: Message-ID: <1430503071479-4823612.post@n4.nabble.com> We should think about moving TranscriptStream out of the Collections package because of its dependencies. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-626-mcz-tp4823611p4823612.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Fri May 1 18:49:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:49:35 2015 Subject: [squeak-dev] The Trunk: ST80-mt.183.mcz Message-ID: Marcel Taeumel uploaded a new version of ST80 to project The Trunk: http://source.squeak.org/trunk/ST80-mt.183.mcz ==================== Summary ==================== Name: ST80-mt.183 Author: mt Time: 1 May 2015, 8:49:18.781 pm UUID: 2a9e776d-332f-1745-b070-49786b01e8b7 Ancestors: ST80-dtl.182 Some assumptions on model interface removed. =============== Diff against ST80-dtl.182 =============== Item was changed: ----- Method: StringHolderController>>userHasNotEdited (in category 'edit flag') ----- userHasNotEdited "Note that my text is free of user edits." + model changed: #clearUserEdits.! - model clearUserEditFlag - ! Item was changed: ----- Method: StringHolderView>>promptForCancel (in category 'updating') ----- promptForCancel "Ask if it is OK to cancel changes to text" | okToCancel stripes | self topView isCollapsed ifTrue: [(self confirm: 'Changes have not been saved. + Is it OK to cancel those changes?' translated) ifTrue: [model changed: #clearUserEdits]. - Is it OK to cancel those changes?' translated) ifTrue: [model clearUserEditFlag]. ^ self]. stripes := (Form extent: 16@16 fromStipple: 16r36C9) bits. Display border: self insetDisplayBox width: 4 rule: Form reverse fillColor: stripes. okToCancel := self confirm: 'Changes have not been saved. Is it OK to cancel those changes?' translated. Display border: self insetDisplayBox width: 4 rule: Form reverse fillColor: stripes. okToCancel ifTrue: [self updateDisplayContents. + model changed: #clearUserEdits]. - model clearUserEditFlag]. ! From commits at source.squeak.org Fri May 1 18:52:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 18:52:48 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.956.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.956.mcz ==================== Summary ==================== Name: Morphic-mt.956 Author: mt Time: 1 May 2015, 8:52:04.62 pm UUID: 9c194491-b261-5b4b-8e79-9806c257dc69 Ancestors: Morphic-mt.955 Some assumptions on model interface removed from text fields. Missing #appendEntryLater added to text fields, which is needed for deferred transcript updates. =============== Diff against Morphic-mt.955 =============== Item was changed: ----- Method: PluggableTextMorph>>promptForCancel (in category 'unaccepted edits') ----- promptForCancel "Ask if it is OK to cancel changes to text" (self confirm: 'Changes have not been saved. Is it OK to cancel those changes?' translated) + ifTrue: [model changed: #clearUserEdits]. - ifTrue: [model clearUserEditFlag]. ! Item was changed: ----- Method: PluggableTextMorph>>update: (in category 'updating') ----- update: aSymbol aSymbol ifNil: [^self]. aSymbol == #flash ifTrue: [^self flash]. aSymbol == getTextSelector ifTrue: [ self setText: self getText. getSelectionSelector ifNotNil: [self setSelection: self getSelection]. ^ self]. aSymbol == getSelectionSelector ifTrue: [^self setSelection: self getSelection]. (aSymbol == #autoSelect and: [getSelectionSelector notNil]) ifTrue: [self handleEdit: [(textMorph editor) abandonChangeText; "no replacement!!" setSearch: model autoSelectString; againOrSame: true]]. aSymbol == #clearUserEdits ifTrue: [^self hasUnacceptedEdits: false]. aSymbol == #wantToChange ifTrue: [self canDiscardEdits ifFalse: [^self promptForCancel]. ^self]. aSymbol == #appendEntry ifTrue: [self handleEdit: [self appendEntry]. ^self refreshWorld]. + aSymbol == #appendEntryLater + ifTrue: [self handleEdit: [self appendEntry]]. aSymbol == #clearText ifTrue: [self handleEdit: [self changeText: Text new]. ^self refreshWorld]. aSymbol == #bs ifTrue: [self handleEdit: [self bsText]. ^self refreshWorld]. aSymbol == #codeChangedElsewhere ifTrue: [self hasEditingConflicts: true. ^self changed]. aSymbol == #saveContents ifTrue: [^self saveContentsInFile]! From leves at elte.hu Fri May 1 21:40:06 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri May 1 21:40:11 2015 Subject: [squeak-dev] The Inbox: Collections-ul.624.mcz In-Reply-To: References: Message-ID: While I was trying to resurrect Character's ClassificationTable, I found that Unicode's ToLower and ToUpper table are initialized incorrectly. I changed the initialization code in Multilingual-ul.209 (and 208), which now uses the UnicodeData.txt file instead of CaseFolding.txt. This means that all #asUppercase and #asLowercase implementations will behave slightly differently (the worst one was Character's, which was still based on some LatinX encoding for byte characters). To review the changes load Multilingual-ul.209 from the Inbox first, then merge Collections-ul.624, and finally merge Collections-ul.625. Levente On Fri, 1 May 2015, commits@source.squeak.org wrote: > A new version of Collections was added to project The Inbox: > http://source.squeak.org/inbox/Collections-ul.624.mcz > > ==================== Summary ==================== > > Name: Collections-ul.624 > Author: ul > Time: 1 May 2015, 1:40:09.445 pm > UUID: a89640e5-e0cc-44e1-9613-e065b78258ad > Ancestors: Collections-tfel.623 > > Various improvements related to Characters and Strings. > > Resurrected Character's ClassificationTable > - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) > - added a bit for #isDigit > - added a mask for #isAlphaNumeirc > - use 0 as a tag if the uppercase or lowercase character value is greater than 255 > - initialize the table in the postscript (to not infere with #initialize) > > Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? > > Simpler and faster Character >> #tokenish. > > Simpler and faster String >> #withoutLineEndings. > > Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. > > =============== Diff against Collections-tfel.623 =============== > > Item was changed: > Magnitude subclass: #Character > instanceVariableNames: 'value' > + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' > - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' > poolDictionaries: '' > category: 'Collections-Strings'! > > !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! > I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. > > The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. > > The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. > > I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! > > Item was changed: > ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- > initializeClassificationTable > + "Initialize the classification table. > + The classification table is a compact encoding of upper and lower cases and digits of characters with > + - bits 0-7: The lower case value of this character or 0, if its greater than 255. > + - bits 8-15: The upper case value of this character or 0, if its greater than 255. > + - bit 16: lowercase bit (isLowercase == true) > + - bit 17: uppercase bit (isUppercase == true) > + - bit 18: digit bit (isDigit == true)" > + " self initializeClassificationTable " > - " > - Initialize the classification table. The classification table is a > - compact encoding of upper and lower cases of characters with > > + | encodedCharSet | > + "Base the table on the EncodedCharset of these characters' leadingChar - 0." > + encodedCharSet := EncodedCharSet charsetAt: 0. > - - bits 0-7: The lower case value of this character. > - - bits 8-15: The upper case value of this character. > - - bit 16: lowercase bit (e.g., isLowercase == true) > - - bit 17: uppercase bit (e.g., isUppercase == true) > > - " > - | ch1 | > - > LowercaseBit := 1 bitShift: 16. > UppercaseBit := 1 bitShift: 17. > + DigitBit := 1 bitShift: 18. > > + "Initialize the letter mask (e.g., isLetter == true)" > + LetterMask := LowercaseBit bitOr: UppercaseBit. > - "Initialize the letter bits (e.g., isLetter == true)" > - LetterBits := LowercaseBit bitOr: UppercaseBit. > > + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" > + AlphaNumericMask := LetterMask bitOr: DigitBit. > - ClassificationTable := Array new: 256. > - "Initialize the defaults (neither lower nor upper case)" > - 0 to: 255 do:[:i| > - ClassificationTable at: i+1 put: (i bitShift: 8) + i. > - ]. > > + "Initialize the table based on encodedCharSet." > + ClassificationTable := Array new: 256. > + 0 to: 255 do: [ :code | > + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | > + isLowercase := encodedCharSet isLowercaseCode: code. > + isUppercase := encodedCharSet isUppercaseCode: code. > + isDigit := encodedCharSet isDigitCode: code. > + lowercaseCode := encodedCharSet toLowercaseCode: code. > + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. > + uppercaseCode := encodedCharSet toUppercaseCode: code. > + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. > + value := (uppercaseCode bitShift: 8) + lowercaseCode. > + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. > + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. > + isDigit ifTrue: [ value := value bitOr: DigitBit ]. > + ClassificationTable at: code + 1 put: value ]! > - "Initialize character pairs (upper-lower case)" > - #( > - "Basic roman" > - ($A $a) ($B $b) ($C $c) ($D $d) > - ($E $e) ($F $f) ($G $g) ($H $h) > - ($I $i) ($J $j) ($K $k) ($L $l) > - ($M $m) ($N $n) ($O $o) ($P $p) > - ($Q $q) ($R $r) ($S $s) ($T $t) > - ($U $u) ($V $v) ($W $w) ($X $x) > - ($Y $y) ($Z $z) > - "International" > - ($? $?) ($? $?) ($? $?) ($? $?) > - ($? $?) ($? $?) ($? $?) ($? $?) > - ($? $?) ($? $?) ($? $?) ($? $?) > - "International - Spanish" > - ($? $?) ($? $?) ($? $?) ($? $?) > - "International - PLEASE CHECK" > - ($? $?) ($? $?) ($? $?) ($? $?) > - ($? $?) ($? $?) > - ($? $?) ($? $?) ($? $?) ($? $?) ($? $?) > - ) do:[:pair| | ch2 | > - ch1 := pair first asciiValue. > - ch2 := pair last asciiValue. > - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. > - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. > - ]. > - > - "Initialize a few others for which we only have lower case versions." > - #($? $? $? $?) do:[:char| > - ch1 := char asciiValue. > - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. > - ]. > - ! > > Item was changed: > ----- Method: Character>>encodedCharSet (in category 'accessing') ----- > encodedCharSet > + > + value < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" > - > ^EncodedCharSet charsetAt: self leadingChar > ! > > Item was changed: > ----- Method: Character>>tokenish (in category 'testing') ----- > tokenish > + "Answer whether the receiver is a valid token-character--letter, digit, or colon." > - "Answer whether the receiver is a valid token-character--letter, digit, or > - colon." > > + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. > + ^self == $: or: [ self isAlphaNumeric ]! > - ^ self == $_ > - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] > - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! > > Item was changed: > ----- Method: String>>withoutLineEndings (in category 'converting') ----- > withoutLineEndings > > + ^self withLineEndings: ' '! > - ^ self withSqueakLineEndings > - copyReplaceAll: String cr > - with: ' ' > - asTokens: false! > > Item was changed: > ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- > numArgs: n > "Answer a string that can be used as a selector with n arguments. > TODO: need to be extended to support shrinking and for selectors like #+ " > > + | numArgs offset |. > + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. > + numArgs = 0 > + ifTrue: [ offset := 1 ] > + ifFalse: [ offset := 0 ]. > + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | > + stream nextPutAll: self. > + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. > + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! > - | numArgs aStream offs |. > - (numArgs := self numArgs) >= n ifTrue: [^self]. > - aStream := WriteStream on: (String new: 16). > - aStream nextPutAll: self. > - > - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. > - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. > - ^aStream contents asSymbol! > > Item was changed: > + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'! > - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! > > > From commits at source.squeak.org Fri May 1 21:55:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 1 21:55:04 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150501215503.5466.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-April/008190.html Name: Collections-nice.622 Ancestors: Collections-mt.621 #toBraceStack: is not used for compiling { } for so long that it's really time to get rid of it. Symbol>>numArgs: does not need to copy self into a temp var. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-April/008191.html Name: GetText-nice.36 Ancestors: GetText-kfr.35 Though it can't really be tested in current trunk image state (InternalTranslator is not initialized) , modernize the way to utf8+gzip+base64 encode... This how how simpler the world could be without those Multi RW Binary or Text things, no need to send those reset/ascii/binary incantations. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008192.html Name: CollectionsTests-tfel.240 Ancestors: CollectionsTests-mt.239 Add a test case to check that ByteString>>findSubstring:in:startingAt:matchTable: behaves the same way as the primitive implementation (esp when using a negative index for startingAt:) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008193.html Name: Collections-tfel.623 Ancestors: Collections-nice.622 fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008194.html Name: Morphic-mt.953 Ancestors: Morphic-mt.952 Text editor hooks modified to be more descriptive on model side. And to not confuse Tweak. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008195.html Name: MorphicTests-mt.29 Ancestors: MorphicTests-mt.28 Tests added for text editor's model callbacks. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008196.html Name: EToys-mt.124 Ancestors: EToys-topa.123 Tiles-view check moved from Tools package. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008197.html Name: MorphicExtras-mt.162 Ancestors: MorphicExtras-mt.161 Added from Morph package. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008198.html Name: Morphic-mt.954 Ancestors: Morphic-mt.953 Deprecations updated and some dependencies to MorphicExtras removed. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008199.html Name: Tools-mt.613 Ancestors: Tools-mt.612 Deprecations updated. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008200.html Name: 46Deprecated-mt.1 Ancestors: Some deprecations for 4.6 added. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008201.html Name: Kernel-nice.921 Ancestors: Kernel-topa.920 Provide an exact version for #floorLog: for those Number using exact arithmetic (as proposed in inbox Kernel-nice.721 / 11 December 2012). Previous version was not exact, otherwise this count would have been zero: (-300 to: -1) count: [:n | n ~= ((10 raisedTo: n) floorLog: 10)]. Note that this won't make #log: exact, and could lead to disagreement between the two functions. However, old behavior compatible with log: is still possible by passing the radix argument asFloat, so this is not a real problem. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008202.html Name: KernelTests-nice.293 Ancestors: KernelTests-mt.292 Tests asserting floorLog: exactness for Number performing exact arithmetic. This was inbox KernelTests-nice.239 / 11 December 2012 ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008203.html Name: Kernel-nice.922 Ancestors: Kernel-nice.921 Remove an un-necessary inst. var. shadowing (inbox Kernel-nice.745 7 March 2013) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008204.html Name: Kernel-nice.923 Ancestors: Kernel-nice.922 Use an intermediate abstract Float representation (sign, exponent, significand) in order to convert single precision bits to double precision bits rather than attempting the conversion by direct bit manipulations. This lead to simpler code, because it is like a semantic bit manipulation rather than a raw bit manipulation. And this also lead to faster code on 32 bits interpreter/COG/Spur VM thanks to avoidance of LargeInteger (was Kernel-nice.893 / 24 December 2014) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008205.html Name: Collections-tfel.624 Ancestors: Collections-tfel.623 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008206.html Name: Collections-mt.625 Ancestors: Collections-tfel.624 Speed-up #endsWith: for strings. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008207.html Name: Morphic-mt.955 Ancestors: Morphic-mt.954 Flag about a performance issue in scroll bars added. We should improve that at some point. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008208.html Name: Tools-mt.614 Ancestors: Tools-mt.613 Some descriptive balloon texts added to browser's switch buttons. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008209.html Name: SMLoader-mt.82 Ancestors: SMLoader-cmm.81 Fixed layout problems and selection bugs in SqueakMap tools. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008210.html Name: Tools-mt.615 Ancestors: Tools-mt.614 Use code panes in inspector and object explorer (was text panes). ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008211.html Name: ShoutCore-ul.46 Ancestors: ShoutCore-ul.45 SHParserST80 performance improvements: - store the allowUnderscoreAssignments and allowUnderscoreSelectors preferences in instance variables - don't honor per class allowUnderscoreAssignments preferences anymore (just like how allowUnderscoreSelectors works) - ensure that instanceVariables is always an Array - reordered branches in some methods based on the methods of the Morph class as sample - use quick returns in frequently used testing methods - release the errorBlock in #parse, instead of an #ensure: block in #parse: - decreased the initial size of ranges to 40 - use Symbol >> #lookup: instead of Symbol >> #hasInterned:ifTrue: - use the fact that classOrMetaClass is nil when it's not a Behavior - use a fast primitive in #scanComment instead of a loop ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008212.html Name: ShoutCore-ul.47 Ancestors: ShoutCore-ul.46 Removed encodedCharSet from SHParserST80. All methods referencing it are sending the corresponding method to the character again. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008213.html Name: Collections-mt.626 Ancestors: Collections-mt.625 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008214.html Name: ST80-mt.183 Ancestors: ST80-dtl.182 Some assumptions on model interface removed. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008215.html Name: Morphic-mt.956 Ancestors: Morphic-mt.955 Some assumptions on model interface removed from text fields. Missing #appendEntryLater added to text fields, which is needed for deferred transcript updates. ============================================= From karlramberg at gmail.com Fri May 1 22:06:26 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri May 1 22:06:28 2015 Subject: [squeak-dev] Re: Font handling In-Reply-To: References: Message-ID: I have taken a look at TextMorph textStyle which seem superfluous. All textStyle is either handled by the paragraph or the the runs in Text. It seems we can replace all references to TextMorph textStyle instance variable to paragraph textstyle without any side effects. But I guess we must keep the instance variable for backwards compability. On Thu, Apr 30, 2015 at 2:29 PM, karl ramberg wrote: > Hi, > the current font handling could need a refactoring/ cleanup. > Emphasis of a font are stored in different places and that makes it > inconsistent and very hard to interface. > > As far as I can tell should the emphasis info be stored as a text > attribute. > But it seems that many tools set the emphasis directly in the font. > > Here is a couple of examples from text in Workspaces: > > {a TextEmphasis code: 1 . aTextFontReference(TTCFont(BitstreamVeraSansMono > 24 Bold Oblique))} > This font has bold and italics set in the font (corresponds to value 3), > but the emphasis attribute is 1 which corresponds to bold. > > {a TextFontReference(a StrikeFont(Accumon10 12))} > Here is also emphasis set in the font and no emphasis attribute is present > at all. > > > Karl > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150502/76b65ba9/attachment.htm From marcel.taeumel at student.hpi.uni-potsdam.de Sat May 2 06:19:45 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat May 2 06:35:03 2015 Subject: [squeak-dev] Re: The Inbox: Collections-ul.624.mcz In-Reply-To: References: Message-ID: <1430547585886-4823678.post@n4.nabble.com> Nice! :) -- View this message in context: http://forum.world.st/The-Inbox-Collections-ul-624-mcz-tp4823607p4823678.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Sat May 2 06:21:12 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat May 2 06:36:30 2015 Subject: [squeak-dev] Re: The Trunk: Collections-tfel.623.mcz In-Reply-To: References: <1430491163940-4823567.post@n4.nabble.com> Message-ID: <1430547672184-4823679.post@n4.nabble.com> If we change the primitive and signal an error, existing projects will break. It's a tricky situation. :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-tfel-623-mcz-tp4823453p4823679.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From timfelgentreff at gmail.com Sat May 2 08:48:15 2015 From: timfelgentreff at gmail.com (timfelgentreff) Date: Sat May 2 09:03:35 2015 Subject: [squeak-dev] Re: The Trunk: Collections-tfel.623.mcz In-Reply-To: <1430547672184-4823679.post@n4.nabble.com> References: <1430491163940-4823567.post@n4.nabble.com> <1430547672184-4823679.post@n4.nabble.com> Message-ID: <1430556495929-4823705.post@n4.nabble.com> I agree with Marcel - we even have code in the trunk image that passes negative indices. I would also, in the long run, like to fix the primitive to not accept negative indices. But I don't like to break people's stuff too quickly, so I think we should have a deprecation warning for the current behavior before fixing it. -- View this message in context: http://forum.world.st/The-Trunk-Collections-tfel-623-mcz-tp4823453p4823705.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Sat May 2 10:37:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 10:37:01 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.957.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.957.mcz ==================== Summary ==================== Name: Morphic-mt.957 Author: mt Time: 2 May 2015, 12:36:22.238 pm UUID: d62a1d6a-7876-b44b-9d23-71ade2abb0e9 Ancestors: Morphic-mt.956 Allow models to trigger accept/revert changes in pluggable text morphs. Why? Provides an additional, more general way besides context menus or keyboard shortcuts. =============== Diff against Morphic-mt.956 =============== Item was changed: ----- Method: PluggableTextMorph>>update: (in category 'updating') ----- update: aSymbol aSymbol ifNil: [^self]. aSymbol == #flash ifTrue: [^self flash]. + aSymbol == getTextSelector ifTrue: [ self setText: self getText. getSelectionSelector ifNotNil: [self setSelection: self getSelection]. ^ self]. aSymbol == getSelectionSelector ifTrue: [^self setSelection: self getSelection]. + + aSymbol == #acceptChanges ifTrue: [^ self accept]. + aSymbol == #revertChanges ifTrue: [^ self cancel]. + (aSymbol == #autoSelect and: [getSelectionSelector notNil]) ifTrue: [self handleEdit: [(textMorph editor) abandonChangeText; "no replacement!!" setSearch: model autoSelectString; againOrSame: true]]. aSymbol == #clearUserEdits ifTrue: [^self hasUnacceptedEdits: false]. aSymbol == #wantToChange ifTrue: [self canDiscardEdits ifFalse: [^self promptForCancel]. ^self]. aSymbol == #appendEntry ifTrue: [self handleEdit: [self appendEntry]. ^self refreshWorld]. aSymbol == #appendEntryLater ifTrue: [self handleEdit: [self appendEntry]]. aSymbol == #clearText ifTrue: [self handleEdit: [self changeText: Text new]. ^self refreshWorld]. aSymbol == #bs ifTrue: [self handleEdit: [self bsText]. ^self refreshWorld]. aSymbol == #codeChangedElsewhere ifTrue: [self hasEditingConflicts: true. ^self changed]. aSymbol == #saveContents ifTrue: + [^self saveContentsInFile]. + ! - [^self saveContentsInFile]! From commits at source.squeak.org Sat May 2 10:38:42 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 10:38:43 2015 Subject: [squeak-dev] The Trunk: MorphicTests-mt.30.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicTests to project The Trunk: http://source.squeak.org/trunk/MorphicTests-mt.30.mcz ==================== Summary ==================== Name: MorphicTests-mt.30 Author: mt Time: 2 May 2015, 12:38:36.255 pm UUID: 30f9a538-e3fa-034a-a612-123cf964e938 Ancestors: MorphicTests-mt.29 Tests added for pluggable text morphs. =============== Diff against MorphicTests-mt.29 =============== Item was added: + TestCase subclass: #PluggableTextMorphTest + instanceVariableNames: 'widget model' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Widgets'! Item was added: + ----- Method: PluggableTextMorphTest>>setUp (in category 'running') ----- + setUp + + super setUp. + + model := ValueHolder new contents: ''; yourself. + widget := PluggableTextMorph on: model text: #contents accept: #contents:.! Item was added: + ----- Method: PluggableTextMorphTest>>test01TextChangeInModel (in category 'tests') ----- + test01TextChangeInModel + + model contents: 'Hello, World!!'. + self assert: model contents equals: widget text asString.! Item was added: + ----- Method: PluggableTextMorphTest>>test02TextChangeInWidget (in category 'tests') ----- + test02TextChangeInWidget + + widget replaceSelectionWith: 'Hello, World!!'. + self assert: '' equals: model contents. + + widget accept. + self assert: widget text asString equals: model contents asString.! Item was added: + ----- Method: PluggableTextMorphTest>>test03TriggerAcceptFromModel (in category 'tests') ----- + test03TriggerAcceptFromModel + + widget replaceSelectionWith: 'Hello, World!!'. + self assert: widget hasUnacceptedEdits. + + model changed: #acceptChanges. + self assert: widget text asString equals: model contents asString.! Item was added: + ----- Method: PluggableTextMorphTest>>test04TriggerAcceptFromWidget (in category 'tests') ----- + test04TriggerAcceptFromWidget + + widget replaceSelectionWith: 'Hello, World!!'. + self assert: widget hasUnacceptedEdits. + + widget accept. + self assert: widget text asString equals: model contents asString.! From commits at source.squeak.org Sat May 2 11:53:22 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 11:53:23 2015 Subject: [squeak-dev] The Trunk: ShoutCore-ul.48.mcz Message-ID: Levente Uzonyi uploaded a new version of ShoutCore to project The Trunk: http://source.squeak.org/trunk/ShoutCore-ul.48.mcz ==================== Summary ==================== Name: ShoutCore-ul.48 Author: ul Time: 2 May 2015, 1:52:29.292 pm UUID: 5ad6f857-2c78-4d6d-8dce-ce8ff7d837c5 Ancestors: ShoutCore-ul.47 SHMCClassDefinition changes: - Implemented the missing #withAllSuperclassesDo: - #withAllSuperclasses uses #withAllSuperclassesDo:, and returns an OrderedCollection with the classes in the same order as in Behavior's implementation. - Recategorized some methods. Use #withAllSuperclassesDo: instead of #withAllSuperclasses in all methods of SHParserST80. Updated TextAction >> #shoutShouldPreserve to reflect the original intention - preserve all TextAction attributes. Slightly faster SHTextStylerST80 >> #setAttributesIn:fromRanges:. Removed the now useless SHTextStylerST80 >> #shouldPreserveAttribute:. =============== Diff against ShoutCore-ul.47 =============== Item was changed: + ----- Method: SHMCClassDefinition>>allInstVarNames (in category 'act like a class') ----- - ----- Method: SHMCClassDefinition>>allInstVarNames (in category 'accessing') ----- allInstVarNames | superclassOrDef answer classOrDef instVars| answer := meta ifTrue:[classDefinition classInstVarNames asArray] ifFalse:[ classDefinition instVarNames asArray]. classOrDef := classDefinition. [superclassOrDef := (classOrDef isKindOf: MCClassDefinition) ifTrue:[ |s| s := classOrDef superclassName. items detect: [:ea | ea isClassDefinition and: [ea className = s]] ifNone: [Smalltalk at: s asSymbol ifAbsent:[nil]]] ifFalse:[ | sc | sc := classOrDef superclass. sc ifNotNil:[ items detect: [:ea | ea isClassDefinition and: [ea className = sc name asString]] ifNone: [sc] ]]. superclassOrDef isNil ] whileFalse:[ instVars := (superclassOrDef isKindOf: MCClassDefinition) ifTrue:[ meta ifTrue:[superclassOrDef classInstVarNames] ifFalse:[superclassOrDef instVarNames]] ifFalse:["real" meta ifTrue:[superclassOrDef theNonMetaClass class instVarNames] ifFalse:[superclassOrDef theNonMetaClass instVarNames]]. answer := answer, instVars. classOrDef := superclassOrDef]. ^answer! Item was changed: + ----- Method: SHMCClassDefinition>>shoutParserClass (in category 'act like a class') ----- - ----- Method: SHMCClassDefinition>>shoutParserClass (in category 'accessing') ----- shoutParserClass "Answer the parser class" ^SHParserST80! Item was changed: + ----- Method: SHMCClassDefinition>>withAllSuperclasses (in category 'act like a class') ----- - ----- Method: SHMCClassDefinition>>withAllSuperclasses (in category 'accessing') ----- withAllSuperclasses + + | result | + result := OrderedCollection new. + self withAllSuperclassesDo: [ :each | result addFirst: each ]. + ^result! - | superclassOrDef answer classOrDef | - - answer := Array with: self. - classOrDef := classDefinition. - [superclassOrDef := (classOrDef isKindOf: MCClassDefinition) - ifTrue:[ |s| - s := classOrDef superclassName. - items - detect: [:ea | ea isClassDefinition and: [ea className = s]] - ifNone: [Smalltalk at: s asSymbol ifAbsent:[nil]]] - ifFalse:[ | sc | - sc := classOrDef superclass. - sc ifNotNil:[ - items - detect: [:ea | ea isClassDefinition and: [ea className = sc name asString]] - ifNone: [sc] ]]. - superclassOrDef isNil - ] whileFalse:[ - answer := answer, (Array with: superclassOrDef). - classOrDef := superclassOrDef]. - ^answer! Item was added: + ----- Method: SHMCClassDefinition>>withAllSuperclassesDo: (in category 'act like a class') ----- + withAllSuperclassesDo: aBlock + + | superclassOrDef classOrDef | + aBlock value: self. + classOrDef := classDefinition. + [ + superclassOrDef := (classOrDef isKindOf: MCClassDefinition) + ifTrue: [ + | superclassName | + superclassName := classOrDef superclassName. + items + detect: [ :each | + each isClassDefinition and: [ + each className = superclassName ] ] + ifNone: [ Smalltalk classNamed: superclassName ] ] + ifFalse: [ + classOrDef superclass ifNotNil: [ :superclass | + | superclassName | + superclassName := superclass name asString. + items + detect: [ :each | + each isClassDefinition and: [ + each className = superclassName ] ] + ifNone: [ superclass ] ] ]. + superclassOrDef isNil ] + whileFalse: [ + aBlock value: superclassOrDef. + classOrDef := superclassOrDef ]! Item was changed: ----- Method: SHParserST80>>resolvePartial: (in category 'identifier testing') ----- resolvePartial: aString "check if any identifier begins with aString" (#('self' 'super' 'true' 'false' 'nil' 'thisContext') anySatisfy: [:each | each beginsWith: aString]) ifTrue: [^#incompleteIdentifier]. (self isIncompleteBlockTempName: aString) ifTrue: [^#incompleteIdentifier]. (self isIncompleteBlockArgName: aString) ifTrue: [^#incompleteIdentifier]. (self isIncompleteMethodTempName: aString) ifTrue: [^#incompleteIdentifier]. (self isIncompleteMethodArgName: aString) ifTrue: [^#incompleteIdentifier]. (instanceVariables anySatisfy: [:each | each beginsWith: aString]) ifTrue: [^#incompleteIdentifier]. workspace ifNotNil: [(workspace hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. classOrMetaClass ifNotNil: [ + classOrMetaClass theNonMetaClass withAllSuperclassesDo: [:c | - classOrMetaClass theNonMetaClass withAllSuperclasses do: [:c | (c classPool hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]. c sharedPools do: [:p | (p hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. (c environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]] ifNil: [(environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. ^#undefinedIdentifier! Item was changed: ----- Method: SHParserST80>>resolvePartialPragmaArgument: (in category 'identifier testing') ----- resolvePartialPragmaArgument: aString "check if any valid pragma argument begins with aString" (#('true' 'false' 'nil') anySatisfy: [:each | each beginsWith: aString]) ifTrue: [^#incompleteIdentifier]. "should really check that a matching binding is for a Class?" classOrMetaClass ifNotNil: [ + classOrMetaClass theNonMetaClass withAllSuperclassesDo: [:c | - classOrMetaClass theNonMetaClass withAllSuperclasses do: [:c | (c environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]] ifNil: [(environment hasBindingThatBeginsWith: aString) ifTrue: [^#incompleteIdentifier]]. ^#undefinedIdentifier! Item was changed: ----- Method: SHParserST80>>resolvePragmaArgument: (in category 'identifier testing') ----- resolvePragmaArgument: aString (#('true' 'false' 'nil') includes: aString) ifTrue: [^aString asSymbol]. "should really check that global is a class?" (Symbol lookup: aString) ifNotNil: [:sym | classOrMetaClass ifNotNil: [ + classOrMetaClass theNonMetaClass withAllSuperclassesDo: [:c | - classOrMetaClass theNonMetaClass withAllSuperclasses do: [:c | (c environment bindingOf: sym) ifNotNil: [^#globalVar]]] ifNil: [(environment bindingOf: sym) ifNotNil: [^#globalVar]]]. ^self resolvePartialPragmaArgument: aString! Item was changed: ----- Method: SHTextStylerST80>>setAttributesIn:fromRanges: (in category 'private') ----- setAttributesIn: aText fromRanges: ranges | charAttr defaultAttr attr newRuns newValues lastAttr oldRuns lastCount | oldRuns := aText runs. defaultAttr := self attributesFor: #default. + charAttr := Array new: aText size withAll: defaultAttr. + ranges do: [ :range | + (self attributesFor: range type) ifNotNil: [ :attribute | + charAttr from: range start to: range end put: attribute ] ]. + newRuns := OrderedCollection new: ranges size * 2 + 1. + newValues := OrderedCollection new: ranges size * 2 + 1. + lastAttr := nil. + lastCount := 0. + 1 to: charAttr size do: [ :i | + (attr := charAttr at: i) == lastAttr - charAttr := Array new: aText size. - 1 to: charAttr size do: [:i | charAttr at: i put: defaultAttr]. - ranges do: [:range | - (attr := self attributesFor: range type) == nil - ifFalse:[ range start to: range end do: [:i | charAttr at: i put: attr]]]. - newRuns := OrderedCollection new: charAttr size // 10. - newValues := OrderedCollection new: charAttr size // 10. - 1 to: charAttr size do: [:i | - attr := charAttr at: i. - i = 1 ifTrue: [ + lastCount := lastCount + 1. + newRuns at: newRuns size put: lastCount ] + ifFalse: [ + newRuns addLast: 1. - newRuns add: 1. lastCount := 1. + lastAttr := newValues addLast: attr ] ]. - lastAttr := newValues add: attr] - ifFalse:[ - attr == lastAttr - ifTrue: [ - lastCount := lastCount + 1. - newRuns at: newRuns size put: lastCount] - ifFalse: [ - newRuns add: 1. - lastCount := 1. - lastAttr := newValues add: attr]]]. aText runs: (RunArray runs: newRuns values: newValues). oldRuns withStartStopAndValueDo:[:start :stop :attribs| + (attribs anySatisfy: [ :each | each shoutShouldPreserve ]) ifTrue: [ + attribs do: [ :each | aText addAttribute: each from: start to: stop ] ] ]. - (attribs anySatisfy: [:each | self shouldPreserveAttribute: each]) - ifTrue: [ - attribs do: [:eachAttrib | aText addAttribute: eachAttrib from: start to: stop]]]. ! Item was removed: - ----- Method: SHTextStylerST80>>shouldPreserveAttribute: (in category 'private') ----- - shouldPreserveAttribute: aTextAttribute - "Answer true if Shout should preserve ALL the attributes in the same run as the argument, - false otherwise" - ^aTextAttribute shoutShouldPreserve! Item was changed: ----- Method: TextAction>>shoutShouldPreserve (in category '*ShoutCore') ----- shoutShouldPreserve + ^true! - ^self class == TextAction! From lewis at mail.msen.com Sat May 2 12:59:10 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat May 2 12:59:12 2015 Subject: [squeak-dev] Re: The Trunk: Collections-tfel.623.mcz In-Reply-To: <1430556495929-4823705.post@n4.nabble.com> References: <1430491163940-4823567.post@n4.nabble.com> <1430547672184-4823679.post@n4.nabble.com> <1430556495929-4823705.post@n4.nabble.com> Message-ID: <20150502125910.GA15311@shell.msen.com> On Sat, May 02, 2015 at 01:48:15AM -0700, timfelgentreff wrote: > I agree with Marcel - we even have code in the trunk image that passes > negative indices. I would also, in the long run, like to fix the primitive > to not accept negative indices. But I don't like to break people's stuff too > quickly, so I think we should have a deprecation warning for the current > behavior before fixing it. > +1 I might add that it is good practice for the image to avoid unnecessary assumptions about the VM. The image may want to run on a variety of VMs implemented in different languages, running on different platforms, and featuring different bugs. But of course the VMs should all be perfect, bug free, and 100% consistent ;-) Dave From lewis at mail.msen.com Sat May 2 13:07:08 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat May 2 13:07:11 2015 Subject: [squeak-dev] Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <1430482995005-4823540.post@n4.nabble.com> References: <1430482995005-4823540.post@n4.nabble.com> Message-ID: <20150502130708.GB15311@shell.msen.com> On Fri, May 01, 2015 at 05:23:15AM -0700, Marcel Taeumel wrote: > Hi --- > > We should unload all historic deprecations... and focus on what is needed > for 46Deprecated (if it cannot be deleted). > It might be better to do this immediately after the next release, rather than before. Removing things can have unintended side effects, so it is good to do it earlier in the release cycle. Dave From Das.Linux at gmx.de Sat May 2 13:13:34 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sat May 2 13:13:40 2015 Subject: [squeak-dev] Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <20150502130708.GB15311@shell.msen.com> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> Message-ID: <25E0F576-79AA-46B1-A36A-9159EE35FF18@gmx.de> On 02.05.2015, at 15:07, David T. Lewis wrote: > On Fri, May 01, 2015 at 05:23:15AM -0700, Marcel Taeumel wrote: >> Hi --- >> >> We should unload all historic deprecations... and focus on what is needed >> for 46Deprecated (if it cannot be deleted). >> > > It might be better to do this immediately after the next release, rather than > before. Removing things can have unintended side effects, so it is good to do > it earlier in the release cycle. Those things (39 and 311) have been deprecated for long, so I'd rather say to lose them right before and keep 45 around one more cycle? Best -Tobias From commits at source.squeak.org Sat May 2 16:27:53 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 16:27:55 2015 Subject: [squeak-dev] The Inbox: Kernel-mtf.924.mcz Message-ID: A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel-mtf.924.mcz ==================== Summary ==================== Name: Kernel-mtf.924 Author: mtf Time: 2 May 2015, 12:26:05.675 pm UUID: 7f688860-5202-4c0d-8ece-8723fe7317d6 Ancestors: Kernel-nice.923 Copied Number >> #round: from Pharo. One of 3 methods needed to make the Artefact pdf library work on squeak: https://sites.google.com/site/artefactpdf/ =============== Diff against Kernel-nice.923 =============== Item was added: + ----- Method: Float>>round: (in category 'truncation and round off') ----- + round: numberOfWishedDecimal + "only leave a fixed amount of decimal" + "10.12345 round: 2 => 10.12" + + | v | + v := 10 raisedTo: numberOfWishedDecimal. + ^ ((self * v) rounded / v) asFloat + ! Item was added: + ----- Method: Fraction>>round: (in category 'truncation and round off') ----- + round: numberOfWishedDecimal + ^self asFloat round: numberOfWishedDecimal! Item was added: + ----- Method: Integer>>round: (in category 'truncation and round off') ----- + round: numberOfWishedDecimal + ^self! Item was added: + ----- Method: Number>>round: (in category 'truncation and round off') ----- + round: numberOfWishedDecimal + self subclassResponsibility! From commits at source.squeak.org Sat May 2 16:38:49 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 16:38:51 2015 Subject: [squeak-dev] The Inbox: KernelTests-mtf.294.mcz Message-ID: A new version of KernelTests was added to project The Inbox: http://source.squeak.org/inbox/KernelTests-mtf.294.mcz ==================== Summary ==================== Name: KernelTests-mtf.294 Author: mtf Time: 2 May 2015, 12:38:13.849 pm UUID: dab760b9-5993-4b22-8b98-855fe72d8117 Ancestors: KernelTests-nice.293 Copied Number >> #round: from Pharo. One of 3 methods needed to make the Artefact pdf library work on squeak: https://sites.google.com/site/artefactpdf/ =============== Diff against KernelTests-nice.293 =============== Item was added: + ----- Method: FloatTest>>testRounding (in category 'tests - rounding') ----- + testRounding + " + self debug: #testRounding + " + + self assert: (10.1234 round: 2) = 10.12. + self assert: (10.1234 round: 0) = 10! Item was added: + ----- Method: FractionTest>>testRounding (in category 'tests - rounding') ----- + testRounding + " + self debug: #testRounding + " + + self assert: ((6/90) round: 2) equals: 0.07! Item was added: + ----- Method: IntegerTest>>testRounding (in category 'test - rounding') ----- + testRounding + " + self debug: #testRounding + " + + self assert: (5 round: 2) equals: 5! From tim at rowledge.org Sat May 2 17:04:18 2015 From: tim at rowledge.org (tim Rowledge) Date: Sat May 2 17:04:23 2015 Subject: [squeak-dev] Re: The Trunk: Collections-tfel.623.mcz In-Reply-To: <20150502125910.GA15311@shell.msen.com> References: <1430491163940-4823567.post@n4.nabble.com> <1430547672184-4823679.post@n4.nabble.com> <1430556495929-4823705.post@n4.nabble.com> <20150502125910.GA15311@shell.msen.com> Message-ID: On 02-05-2015, at 5:59 AM, David T. Lewis wrote: > But of course the VMs should all be perfect, bug free, and 100% consistent ;-) They virtually are... tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim You never really learn to swear until you learn to drive in Silicon Valley From commits at source.squeak.org Sat May 2 17:20:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 17:20:14 2015 Subject: [squeak-dev] The Trunk: Morphic-kfr.958.mcz Message-ID: Karl Ramberg uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-kfr.958.mcz ==================== Summary ==================== Name: Morphic-kfr.958 Author: kfr Time: 2 May 2015, 7:18:54.572 pm UUID: 8235819e-0435-b142-aa1b-7676dd49a995 Ancestors: Morphic-mt.957 Couple of layout and color fixes to NewColorPickerMorph =============== Diff against Morphic-mt.957 =============== Item was changed: ----- Method: NewColorPickerMorph>>newCloseButton (in category 'initialize-release') ----- newCloseButton ^ (PluggableButtonMorph on: self getState: nil action: #delete label: #closeButtonLabel) vResizing: #spaceFill ; + hResizing: #spaceFill; yourself! Item was changed: ----- Method: NewColorPickerMorph>>setup (in category 'initialize-release') ----- setup self + color: (Color white darker) ; - color: (Color white slightlyDarker alpha: 0.88) ; cornerStyle: #rounded ; changeTableLayout ; + hResizing: #shrinkWrap ; + vResizing: #shrinkWrap ; - hResizing: #rigid ; - vResizing: #rigid ; extent: 240@240 ; addMorphBack: hsvaMorph ; addMorphBack: self newColorExpressionMorph ; addMorphBack: self newBottomRow ; layoutInset: 4 ; cellInset: 2. + ! - Preferences menuAppearance3d - ifTrue: [self addDropShadow].! From tapplek at gmail.com Sat May 2 17:46:50 2015 From: tapplek at gmail.com (Tapple Gao) Date: Sat May 2 17:46:53 2015 Subject: [squeak-dev] Using Artefact PDF library in Squeak In-Reply-To: <5544fd9d.619b340a.67a2.ffffadd8SMTPIN_ADDED_MISSING@mx.google.com> References: <5544fd9d.619b340a.67a2.ffffadd8SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <0EE454FD-FF87-4E81-8305-EF75BDCDB07E@gmail.com> Hi all. I put three packages in the inbox that allow all the demos from the Artefact pdf library to run in squeak: Kernel-mtf.924.mcz KernelTests-mtf.294.mcz Collections-mtf.625.mcz They add 3 methods: Number >> round: Collection >> asDictionary Collection >> max: I still have commit access to the Trunk from ages ago, but I have been away from squeak so long I thought I?d put them in the inbox and submit them for review From marcel.taeumel at student.hpi.uni-potsdam.de Sat May 2 18:08:17 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat May 2 18:23:39 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: Message-ID: <1430590097489-4823795.post@n4.nabble.com> Why did you remove the shadow? ;( ... ;) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823795.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Sat May 2 19:16:01 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sat May 2 19:16:06 2015 Subject: [squeak-dev] Using Artefact PDF library in Squeak In-Reply-To: <0EE454FD-FF87-4E81-8305-EF75BDCDB07E@gmail.com> References: <5544fd9d.619b340a.67a2.ffffadd8SMTPIN_ADDED_MISSING@mx.google.com> <0EE454FD-FF87-4E81-8305-EF75BDCDB07E@gmail.com> Message-ID: I've ported it to Squeak[1] about a year ago, but I haven't found the need for any of these methods. Maybe they added them after I forked it. Levente [1] http://leves.web.elte.hu/squeak/Artefact/ On Sat, 2 May 2015, Tapple Gao wrote: > Hi all. > > I put three packages in the inbox that allow all the demos from the Artefact pdf library to run in squeak: > Kernel-mtf.924.mcz > KernelTests-mtf.294.mcz > Collections-mtf.625.mcz > > They add 3 methods: > Number >> round: > Collection >> asDictionary > Collection >> max: > > I still have commit access to the Trunk from ages ago, but I have been away from squeak so long I thought I?d put them in the inbox and submit them for review > From hannes.hirzel at gmail.com Sat May 2 19:27:26 2015 From: hannes.hirzel at gmail.com (H. Hirzel) Date: Sat May 2 19:27:27 2015 Subject: [squeak-dev] Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <25E0F576-79AA-46B1-A36A-9159EE35FF18@gmx.de> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> <25E0F576-79AA-46B1-A36A-9159EE35FF18@gmx.de> Message-ID: +1 In particular as there will be another two or three months until the release takes place.... --Hannes On 5/2/15, Tobias Pape wrote: > > On 02.05.2015, at 15:07, David T. Lewis wrote: > >> On Fri, May 01, 2015 at 05:23:15AM -0700, Marcel Taeumel wrote: >>> Hi --- >>> >>> We should unload all historic deprecations... and focus on what is >>> needed >>> for 46Deprecated (if it cannot be deleted). >>> >> >> It might be better to do this immediately after the next release, rather >> than >> before. Removing things can have unintended side effects, so it is good to >> do >> it earlier in the release cycle. > > Those things (39 and 311) have been deprecated for long, so I'd rather > say to lose them right before and keep 45 around one more cycle? > Best > -Tobias > > > > From leves at elte.hu Sat May 2 19:40:04 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sat May 2 19:40:08 2015 Subject: [squeak-dev] Using Artefact PDF library in Squeak In-Reply-To: References: <5544fd9d.619b340a.67a2.ffffadd8SMTPIN_ADDED_MISSING@mx.google.com> <0EE454FD-FF87-4E81-8305-EF75BDCDB07E@gmail.com> Message-ID: I remember #asDictionary now. This is what happens when you don't want caseOf: and caseOf:otherwise: be in your language: ^PDFDataSymbol symbol: ({ #singlePage->'SinglePage' . #continuousPages->'OneColumn' . #twoPages->'TwoColumnLeft' } asDictionary at: self displayLayout). Or this: ^ ({(#bottomRight -> [ self to ]). (#bottomLeft -> [ self from x @ self to y ]). (#topRight -> [ self to x @ self from y ]). (#topLeft -> [ self from x @ self from y ])} asDictionary at: self orientation) value Etc. Levente On Sat, 2 May 2015, Levente Uzonyi wrote: > I've ported it to Squeak[1] about a year ago, but I haven't found the need > for any of these methods. Maybe they added them after I forked it. > > Levente > > [1] http://leves.web.elte.hu/squeak/Artefact/ > > On Sat, 2 May 2015, Tapple Gao wrote: > >> Hi all. >> >> I put three packages in the inbox that allow all the demos from the >> Artefact pdf library to run in squeak: >> Kernel-mtf.924.mcz >> KernelTests-mtf.294.mcz >> Collections-mtf.625.mcz >> >> They add 3 methods: >> Number >> round: >> Collection >> asDictionary >> Collection >> max: >> >> I still have commit access to the Trunk from ages ago, but I have been away >> from squeak so long I thought I?d put them in the inbox and submit them for >> review > From marcel.taeumel at student.hpi.uni-potsdam.de Sat May 2 19:25:46 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat May 2 19:41:08 2015 Subject: [squeak-dev] Re: Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <20150502130708.GB15311@shell.msen.com> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> Message-ID: <1430594746663-4823811.post@n4.nabble.com> Then I might not quite understand the idea of deprecating things here. :) How many releases should they stay? We should at least add tests so that there are no senders in the image left. Best, Marcel -- View this message in context: http://forum.world.st/Unload-39Deprecated-311Deprecated-and-45Deprecated-in-Trunk-tp4823540p4823811.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Sat May 2 19:27:38 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sat May 2 19:43:00 2015 Subject: [squeak-dev] Re: Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <1430594746663-4823811.post@n4.nabble.com> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> <1430594746663-4823811.post@n4.nabble.com> Message-ID: <1430594858506-4823812.post@n4.nabble.com> Any project that needs those things can load them. Anytime. Why keep them in trunk? Best, Marcel -- View this message in context: http://forum.world.st/Unload-39Deprecated-311Deprecated-and-45Deprecated-in-Trunk-tp4823540p4823812.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Sat May 2 19:45:39 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sat May 2 19:45:43 2015 Subject: [squeak-dev] Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <25E0F576-79AA-46B1-A36A-9159EE35FF18@gmx.de> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> <25E0F576-79AA-46B1-A36A-9159EE35FF18@gmx.de> Message-ID: The problem here is that some of these have assumptions which have never been met. 39Deprecated: - ContextPart >> #methodSelector can be safely removed - SharedQueue2 >> #flush and #flushAllSuchThat: can be removed, but that will make it incompatible with SharedQueue. The migration to SharedQueue2 has not happened yet, so these methods have senders in the image (even if the receiver is not a SharedQueue2). And it's possible that we'll migrate to something else. 311Deprecated: Everything looks safe to be removed. 45Deprecated: Most methods seem to be safe to be removed. Levente On Sat, 2 May 2015, Tobias Pape wrote: > > On 02.05.2015, at 15:07, David T. Lewis wrote: > >> On Fri, May 01, 2015 at 05:23:15AM -0700, Marcel Taeumel wrote: >>> Hi --- >>> >>> We should unload all historic deprecations... and focus on what is needed >>> for 46Deprecated (if it cannot be deleted). >>> >> >> It might be better to do this immediately after the next release, rather than >> before. Removing things can have unintended side effects, so it is good to do >> it earlier in the release cycle. > > Those things (39 and 311) have been deprecated for long, so I'd rather > say to lose them right before and keep 45 around one more cycle? > Best > -Tobias > > > > From Das.Linux at gmx.de Sat May 2 19:49:04 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sat May 2 19:49:09 2015 Subject: [squeak-dev] Re: Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <1430594746663-4823811.post@n4.nabble.com> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> <1430594746663-4823811.post@n4.nabble.com> Message-ID: <867C2D52-DB81-4F4D-A3F1-F5D460756B24@gmx.de> On 02.05.2015, at 21:25, Marcel Taeumel wrote: > Then I might not quite understand the idea of deprecating things here. :) How > many releases should they stay? > n+2. So ideally, 45Deprecated should be removed in 4.7 46Deprecated should be removed in 4.8 and so on. That's how I understand deprecation > We should at least add tests so that there are no senders in the image left. > > Best, > Marcel Best regards -Tobias From lewis at mail.msen.com Sat May 2 19:59:45 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat May 2 19:59:47 2015 Subject: [squeak-dev] Re: Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <1430594858506-4823812.post@n4.nabble.com> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> <1430594746663-4823811.post@n4.nabble.com> <1430594858506-4823812.post@n4.nabble.com> Message-ID: <20150502195945.GA77748@shell.msen.com> On Sat, May 02, 2015 at 12:27:38PM -0700, Marcel Taeumel wrote: > Any project that needs those things can load them. Anytime. Why keep them in > trunk? > I only meant to suggest that it may be better to do it immediately after the release, not that it shouldn't be done. It's the same amount of work either way, just less chance of causing problems for the release image. Nobody who downloads the 5.0/4.6 image would notice the difference either way. Dave From karlramberg at gmail.com Sat May 2 20:06:32 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sat May 2 20:06:35 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: <1430590097489-4823795.post@n4.nabble.com> References: <1430590097489-4823795.post@n4.nabble.com> Message-ID: Ah, that was a slip. New change uploaded Karl On Sat, May 2, 2015 at 8:08 PM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Why did you remove the shadow? ;( ... ;) > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823795.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150502/4cba1b6b/attachment.htm From commits at source.squeak.org Sat May 2 20:06:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 20:06:50 2015 Subject: [squeak-dev] The Trunk: Morphic-kfr.959.mcz Message-ID: Karl Ramberg uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-kfr.959.mcz ==================== Summary ==================== Name: Morphic-kfr.959 Author: kfr Time: 2 May 2015, 10:05:29.163 pm UUID: c3010a30-ff64-574b-8497-227a9b1e75b5 Ancestors: Morphic-kfr.958 Added back drop shadow preference =============== Diff against Morphic-kfr.958 =============== Item was changed: ----- Method: NewColorPickerMorph>>setup (in category 'initialize-release') ----- setup self color: (Color white darker) ; cornerStyle: #rounded ; changeTableLayout ; hResizing: #shrinkWrap ; vResizing: #shrinkWrap ; extent: 240@240 ; addMorphBack: hsvaMorph ; addMorphBack: self newColorExpressionMorph ; addMorphBack: self newBottomRow ; layoutInset: 4 ; cellInset: 2. + Preferences menuAppearance3d + ifTrue: [self addDropShadow]. ! From nicolas.cellier.aka.nice at gmail.com Sat May 2 20:13:11 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sat May 2 20:13:13 2015 Subject: [squeak-dev] The Inbox: Kernel-mtf.924.mcz In-Reply-To: <5544fb11.a19e340a.3cce.014aSMTPIN_ADDED_MISSING@mx.google.com> References: <5544fb11.a19e340a.3cce.014aSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-05-02 18:27 GMT+02:00 : > A new version of Kernel was added to project The Inbox: > http://source.squeak.org/inbox/Kernel-mtf.924.mcz > > ==================== Summary ==================== > > Name: Kernel-mtf.924 > Author: mtf > Time: 2 May 2015, 12:26:05.675 pm > UUID: 7f688860-5202-4c0d-8ece-8723fe7317d6 > Ancestors: Kernel-nice.923 > > Copied Number >> #round: from Pharo. One of 3 methods needed to make the > Artefact pdf library work on squeak: > https://sites.google.com/site/artefactpdf/ > > =============== Diff against Kernel-nice.923 =============== > > Item was added: > + ----- Method: Float>>round: (in category 'truncation and round off') > ----- > + round: numberOfWishedDecimal > + "only leave a fixed amount of decimal" > + "10.12345 round: 2 => 10.12" > + > + | v | > + v := 10 raisedTo: numberOfWishedDecimal. > + ^ ((self * v) rounded / v) asFloat > + ! > > self assert: (Float fmax round: 2) = Float fmax. It's probably not very important for artefact, but if this method has a wider usage than artefact, then it should better be robust to overflow... > Item was added: > + ----- Method: Fraction>>round: (in category 'truncation and round off') > ----- > + round: numberOfWishedDecimal > + ^self asFloat round: numberOfWishedDecimal! > > Transforming exact arithmetic into inexact Float sounds like heresy to me ;) That's a questionable choice. Why this cult to Float would be necessary here? > Item was added: > + ----- Method: Integer>>round: (in category 'truncation and round off') > ----- > + round: numberOfWishedDecimal > + ^self! > > Item was added: > + ----- Method: Number>>round: (in category 'truncation and round off') > ----- > + round: numberOfWishedDecimal > + self subclassResponsibility! > > > If it's subclass responsibility, then it must be implemented in ScaledDecimal. This is not necessary in Pharo, because ScaledDecimal has been moved under Fraction, but it is in Squeak. I'd rather see Float implementation moved up (without the asFloat) and Float invoking super asFloat... I didn't check artefact, but I suspect that the usage is just to printShowingMaxDecimals: numberOfWishedDecimal, which would make the whole method moot. Nicolas -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150502/276d4759/attachment.htm From leves at elte.hu Sat May 2 20:32:31 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sat May 2 20:32:34 2015 Subject: [squeak-dev] The Inbox: Kernel-mtf.924.mcz In-Reply-To: References: <5544fb11.a19e340a.3cce.014aSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Sat, 2 May 2015, Nicolas Cellier wrote: > > > 2015-05-02 18:27 GMT+02:00 : > A new version of Kernel was added to project The Inbox: > http://source.squeak.org/inbox/Kernel-mtf.924.mcz > > ==================== Summary ==================== > > Name: Kernel-mtf.924 > Author: mtf > Time: 2 May 2015, 12:26:05.675 pm > UUID: 7f688860-5202-4c0d-8ece-8723fe7317d6 > Ancestors: Kernel-nice.923 > > Copied Number >> #round: from Pharo. One of 3 methods needed to make the Artefact pdf library work on squeak: > https://sites.google.com/site/artefactpdf/ > > =============== Diff against Kernel-nice.923 =============== > > Item was added: > + ----- Method: Float>>round: (in category 'truncation and round off') ----- > + round: numberOfWishedDecimal > +? ? ? ? ?"only leave a fixed amount of decimal" > +? ? ? ? ?"10.12345 round: 2 => 10.12" > + > +? ? ? ? ?| v | > +? ? ? ? ?v := 10 raisedTo: numberOfWishedDecimal. > +? ? ? ? ?^ ((self * v) rounded / v) asFloat > + ! > > > self assert: (Float fmax round: 2) = Float fmax. > > It's probably not very important for artefact, but if this method has a wider usage than artefact, then it should better be robust to overflow... > ? > Item was added: > + ----- Method: Fraction>>round: (in category 'truncation and round off') ----- > + round: numberOfWishedDecimal > +? ? ? ?^self asFloat round: numberOfWishedDecimal! > > > Transforming exact arithmetic into inexact Float sounds like heresy to me ;) > That's a questionable choice. > Why this cult to Float would be necessary here? > ? > Item was added: > + ----- Method: Integer>>round: (in category 'truncation and round off') ----- > + round: numberOfWishedDecimal > +? ? ? ?^self! > > Item was added: > + ----- Method: Number>>round: (in category 'truncation and round off') ----- > + round: numberOfWishedDecimal > +? ? ? ?self subclassResponsibility! > > > If it's subclass responsibility, then it must be implemented in ScaledDecimal. > This is not necessary in Pharo, because ScaledDecimal has been moved under Fraction, but it is in Squeak. > I'd rather see Float implementation moved up (without the asFloat) and Float invoking super asFloat... > > I didn't check artefact, but I suspect that the usage is just to printShowingMaxDecimals: numberOfWishedDecimal, which would make the whole method > moot. The method was probably written by someone who's not aware of #roundTo:. You're right about the printing thing in Artefact. I replaced #round: with #printOn:maxDecimalPlaces: in my image. Levente > > Nicolas > > From karlramberg at gmail.com Sat May 2 20:36:08 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sat May 2 20:36:10 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> Message-ID: I noticed that NewColorPickerMorph is hard coded to use rounded corners. And that the menu preference is not a pragma preference. But one issue with pragma preferences is a big influx of new preferences scattered all over. Should we have a like a WidgetMorph hierarchy that we can use for all the stuff that should look similar and use the same preferences ?? Karl On Sat, May 2, 2015 at 10:06 PM, karl ramberg wrote: > Ah, that was a slip. > New change uploaded > > Karl > > On Sat, May 2, 2015 at 8:08 PM, Marcel Taeumel < > marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > >> Why did you remove the shadow? ;( ... ;) >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: >> http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823795.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150502/70e79cae/attachment.htm From lewis at mail.msen.com Sat May 2 20:50:43 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat May 2 20:50:45 2015 Subject: [squeak-dev] Re: Unload 39Deprecated, 311Deprecated, and 45Deprecated in Trunk In-Reply-To: <20150502195945.GA77748@shell.msen.com> References: <1430482995005-4823540.post@n4.nabble.com> <20150502130708.GB15311@shell.msen.com> <1430594746663-4823811.post@n4.nabble.com> <1430594858506-4823812.post@n4.nabble.com> <20150502195945.GA77748@shell.msen.com> Message-ID: <20150502205043.GA86239@shell.msen.com> On Sat, May 02, 2015 at 03:59:45PM -0400, David T. Lewis wrote: > On Sat, May 02, 2015 at 12:27:38PM -0700, Marcel Taeumel wrote: > > Any project that needs those things can load them. Anytime. Why keep them in > > trunk? > > > > I only meant to suggest that it may be better to do it immediately after the > release, not that it shouldn't be done. It's the same amount of work either > way, just less chance of causing problems for the release image. Nobody who > downloads the 5.0/4.6 image would notice the difference either way. > Sorry, please disregard. I'm falling behind :-( Dave From asqueaker at gmail.com Sat May 2 21:00:17 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat May 2 21:00:19 2015 Subject: [squeak-dev] pre-debugger buttons are backward Message-ID: I've been pressing the wrong button all day, does anyone know how this happened or, more importantly, how to fix it back? Proceed is definitely the button that should come first, not Debug. Thanks. From nicolas.cellier.aka.nice at gmail.com Sat May 2 21:04:27 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sat May 2 21:04:28 2015 Subject: [squeak-dev] The Inbox: Kernel-mtf.924.mcz In-Reply-To: References: <5544fb11.a19e340a.3cce.014aSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-05-02 22:32 GMT+02:00 Levente Uzonyi : > On Sat, 2 May 2015, Nicolas Cellier wrote: > > >> >> 2015-05-02 18:27 GMT+02:00 : >> A new version of Kernel was added to project The Inbox: >> http://source.squeak.org/inbox/Kernel-mtf.924.mcz >> >> ==================== Summary ==================== >> >> Name: Kernel-mtf.924 >> Author: mtf >> Time: 2 May 2015, 12:26:05.675 pm >> UUID: 7f688860-5202-4c0d-8ece-8723fe7317d6 >> Ancestors: Kernel-nice.923 >> >> Copied Number >> #round: from Pharo. One of 3 methods needed to >> make the Artefact pdf library work on squeak: >> https://sites.google.com/site/artefactpdf/ >> >> =============== Diff against Kernel-nice.923 =============== >> >> Item was added: >> + ----- Method: Float>>round: (in category 'truncation and round >> off') ----- >> + round: numberOfWishedDecimal >> + "only leave a fixed amount of decimal" >> + "10.12345 round: 2 => 10.12" >> + >> + | v | >> + v := 10 raisedTo: numberOfWishedDecimal. >> + ^ ((self * v) rounded / v) asFloat >> + ! >> >> >> self assert: (Float fmax round: 2) = Float fmax. >> >> It's probably not very important for artefact, but if this method has a >> wider usage than artefact, then it should better be robust to overflow... >> >> Item was added: >> + ----- Method: Fraction>>round: (in category 'truncation and round >> off') ----- >> + round: numberOfWishedDecimal >> + ^self asFloat round: numberOfWishedDecimal! >> >> >> Transforming exact arithmetic into inexact Float sounds like heresy to me >> ;) >> That's a questionable choice. >> Why this cult to Float would be necessary here? >> >> Item was added: >> + ----- Method: Integer>>round: (in category 'truncation and round >> off') ----- >> + round: numberOfWishedDecimal >> + ^self! >> >> Item was added: >> + ----- Method: Number>>round: (in category 'truncation and round >> off') ----- >> + round: numberOfWishedDecimal >> + self subclassResponsibility! >> >> >> If it's subclass responsibility, then it must be implemented in >> ScaledDecimal. >> This is not necessary in Pharo, because ScaledDecimal has been moved >> under Fraction, but it is in Squeak. >> I'd rather see Float implementation moved up (without the asFloat) and >> Float invoking super asFloat... >> >> I didn't check artefact, but I suspect that the usage is just to >> printShowingMaxDecimals: numberOfWishedDecimal, which would make the whole >> method >> moot. >> > > The method was probably written by someone who's not aware of #roundTo:.` > No, this is because 'x roundTo: (10 raisedTo: n) reciprocal' is a bit worse than '(x * (10 raisedTo: n) asFloat) rounded / (10 raisedTo: n) asFloat' Indeed, in the first one you perform one more inexact operation (1/100 ~= 0.01). But anyway, these are vain efforts, because #round: in Pharo still cumulates several inexact operations and thus will sometimes fail to deliver the correct answer. For example: self assert: 1.0005 < (5/10000+1) ==> ((1.0005 round: 3) = 1). alas, it answers 1.001 and differs from printShowingMaxDecimalPlaces: 3... Definitely not top quality. I think Pharo did not integrate printShowingMaxDecimalPlaces: so that probably explains the mistake. Or maybe they were influenced by Python round, but should have checked how it is implemented: For example, see https://github.com/python/cpython/blob/c7688b44387d116522ff53c0927169db45969f0e/Python/pymath.c double round(double x) { double absx, y; absx = fabs(x); y = floor(absx); if (absx - y >= 0.5) y += 1.0; return copysign(y, x); } That should translate easily in Smalltalk if REALLY necessary... You're right about the printing thing in Artefact. I replaced #round: with > #printOn:maxDecimalPlaces: in my image. > > Easy to guess, the only other possible use I can think of, is naive monetary apps; that makes two reasons to ban the message ;) Levente > > >> Nicolas >> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150502/e3252554/attachment.htm From nicolas.cellier.aka.nice at gmail.com Sat May 2 21:10:16 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sat May 2 21:10:19 2015 Subject: [squeak-dev] The Inbox: Kernel-mtf.924.mcz In-Reply-To: References: <5544fb11.a19e340a.3cce.014aSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-05-02 23:04 GMT+02:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>: > > > 2015-05-02 22:32 GMT+02:00 Levente Uzonyi : > >> On Sat, 2 May 2015, Nicolas Cellier wrote: >> >> >>> >>> 2015-05-02 18:27 GMT+02:00 : >>> A new version of Kernel was added to project The Inbox: >>> http://source.squeak.org/inbox/Kernel-mtf.924.mcz >>> >>> ==================== Summary ==================== >>> >>> Name: Kernel-mtf.924 >>> Author: mtf >>> Time: 2 May 2015, 12:26:05.675 pm >>> UUID: 7f688860-5202-4c0d-8ece-8723fe7317d6 >>> Ancestors: Kernel-nice.923 >>> >>> Copied Number >> #round: from Pharo. One of 3 methods needed to >>> make the Artefact pdf library work on squeak: >>> https://sites.google.com/site/artefactpdf/ >>> >>> =============== Diff against Kernel-nice.923 =============== >>> >>> Item was added: >>> + ----- Method: Float>>round: (in category 'truncation and round >>> off') ----- >>> + round: numberOfWishedDecimal >>> + "only leave a fixed amount of decimal" >>> + "10.12345 round: 2 => 10.12" >>> + >>> + | v | >>> + v := 10 raisedTo: numberOfWishedDecimal. >>> + ^ ((self * v) rounded / v) asFloat >>> + ! >>> >>> >>> self assert: (Float fmax round: 2) = Float fmax. >>> >>> It's probably not very important for artefact, but if this method has a >>> wider usage than artefact, then it should better be robust to overflow... >>> >>> Item was added: >>> + ----- Method: Fraction>>round: (in category 'truncation and >>> round off') ----- >>> + round: numberOfWishedDecimal >>> + ^self asFloat round: numberOfWishedDecimal! >>> >>> >>> Transforming exact arithmetic into inexact Float sounds like heresy to >>> me ;) >>> That's a questionable choice. >>> Why this cult to Float would be necessary here? >>> >>> Item was added: >>> + ----- Method: Integer>>round: (in category 'truncation and round >>> off') ----- >>> + round: numberOfWishedDecimal >>> + ^self! >>> >>> Item was added: >>> + ----- Method: Number>>round: (in category 'truncation and round >>> off') ----- >>> + round: numberOfWishedDecimal >>> + self subclassResponsibility! >>> >>> >>> If it's subclass responsibility, then it must be implemented in >>> ScaledDecimal. >>> This is not necessary in Pharo, because ScaledDecimal has been moved >>> under Fraction, but it is in Squeak. >>> I'd rather see Float implementation moved up (without the asFloat) and >>> Float invoking super asFloat... >>> >>> I didn't check artefact, but I suspect that the usage is just to >>> printShowingMaxDecimals: numberOfWishedDecimal, which would make the whole >>> method >>> moot. >>> >> >> The method was probably written by someone who's not aware of #roundTo:.` >> > > No, this is because 'x roundTo: (10 raisedTo: n) reciprocal' is a bit > worse than '(x * (10 raisedTo: n) asFloat) rounded / (10 raisedTo: n) > asFloat' > Indeed, in the first one you perform one more inexact operation (1/100 ~= > 0.01). > > But anyway, these are vain efforts, because #round: in Pharo still > cumulates several inexact operations and thus will sometimes fail to > deliver the correct answer. > > For example: > self assert: 1.0005 < (5/10000+1) ==> ((1.0005 round: 3) = 1). > alas, it answers 1.001 and differs from printShowingMaxDecimalPlaces: 3... > Definitely not top quality. > > I think Pharo did not integrate printShowingMaxDecimalPlaces: so that > probably explains the mistake. > Or maybe they were influenced by Python round, but should have checked how > it is implemented: > For example, see > https://github.com/python/cpython/blob/c7688b44387d116522ff53c0927169db45969f0e/Python/pymath.c > > double round(double x) { double absx, y; absx = fabs(x); y = floor(absx); > if (absx - y >= 0.5) y += 1.0; return copysign(y, x); } > Oups, that's round without argument... > > That should translate easily in Smalltalk if REALLY necessary... > > > You're right about the printing thing in Artefact. I replaced #round: with >> #printOn:maxDecimalPlaces: in my image. >> >> > Easy to guess, the only other possible use I can think of, is naive > monetary apps; that makes two reasons to ban the message ;) > > > > Levente >> >> >>> Nicolas >>> >>> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150502/31715ffe/attachment.htm From nicolas.cellier.aka.nice at gmail.com Sat May 2 21:15:09 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sat May 2 21:15:13 2015 Subject: [squeak-dev] The Inbox: Kernel-mtf.924.mcz In-Reply-To: References: <5544fb11.a19e340a.3cce.014aSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-05-02 23:10 GMT+02:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>: > > > 2015-05-02 23:04 GMT+02:00 Nicolas Cellier < > nicolas.cellier.aka.nice@gmail.com>: > >> >> >> 2015-05-02 22:32 GMT+02:00 Levente Uzonyi : >> >>> On Sat, 2 May 2015, Nicolas Cellier wrote: >>> >>> >>>> >>>> 2015-05-02 18:27 GMT+02:00 : >>>> A new version of Kernel was added to project The Inbox: >>>> http://source.squeak.org/inbox/Kernel-mtf.924.mcz >>>> >>>> ==================== Summary ==================== >>>> >>>> Name: Kernel-mtf.924 >>>> Author: mtf >>>> Time: 2 May 2015, 12:26:05.675 pm >>>> UUID: 7f688860-5202-4c0d-8ece-8723fe7317d6 >>>> Ancestors: Kernel-nice.923 >>>> >>>> Copied Number >> #round: from Pharo. One of 3 methods needed to >>>> make the Artefact pdf library work on squeak: >>>> https://sites.google.com/site/artefactpdf/ >>>> >>>> =============== Diff against Kernel-nice.923 =============== >>>> >>>> Item was added: >>>> + ----- Method: Float>>round: (in category 'truncation and round >>>> off') ----- >>>> + round: numberOfWishedDecimal >>>> + "only leave a fixed amount of decimal" >>>> + "10.12345 round: 2 => 10.12" >>>> + >>>> + | v | >>>> + v := 10 raisedTo: numberOfWishedDecimal. >>>> + ^ ((self * v) rounded / v) asFloat >>>> + ! >>>> >>>> >>>> self assert: (Float fmax round: 2) = Float fmax. >>>> >>>> It's probably not very important for artefact, but if this method has a >>>> wider usage than artefact, then it should better be robust to overflow... >>>> >>>> Item was added: >>>> + ----- Method: Fraction>>round: (in category 'truncation and >>>> round off') ----- >>>> + round: numberOfWishedDecimal >>>> + ^self asFloat round: numberOfWishedDecimal! >>>> >>>> >>>> Transforming exact arithmetic into inexact Float sounds like heresy to >>>> me ;) >>>> That's a questionable choice. >>>> Why this cult to Float would be necessary here? >>>> >>>> Item was added: >>>> + ----- Method: Integer>>round: (in category 'truncation and >>>> round off') ----- >>>> + round: numberOfWishedDecimal >>>> + ^self! >>>> >>>> Item was added: >>>> + ----- Method: Number>>round: (in category 'truncation and round >>>> off') ----- >>>> + round: numberOfWishedDecimal >>>> + self subclassResponsibility! >>>> >>>> >>>> If it's subclass responsibility, then it must be implemented in >>>> ScaledDecimal. >>>> This is not necessary in Pharo, because ScaledDecimal has been moved >>>> under Fraction, but it is in Squeak. >>>> I'd rather see Float implementation moved up (without the asFloat) and >>>> Float invoking super asFloat... >>>> >>>> I didn't check artefact, but I suspect that the usage is just to >>>> printShowingMaxDecimals: numberOfWishedDecimal, which would make the whole >>>> method >>>> moot. >>>> >>> >>> The method was probably written by someone who's not aware of #roundTo:.` >>> >> >> No, this is because 'x roundTo: (10 raisedTo: n) reciprocal' is a bit >> worse than '(x * (10 raisedTo: n) asFloat) rounded / (10 raisedTo: n) >> asFloat' >> Indeed, in the first one you perform one more inexact operation (1/100 ~= >> 0.01). >> >> But anyway, these are vain efforts, because #round: in Pharo still >> cumulates several inexact operations and thus will sometimes fail to >> deliver the correct answer. >> >> For example: >> self assert: 1.0005 < (5/10000+1) ==> ((1.0005 round: 3) = 1). >> alas, it answers 1.001 and differs from printShowingMaxDecimalPlaces: 3... >> Definitely not top quality. >> >> I think Pharo did not integrate printShowingMaxDecimalPlaces: so that >> probably explains the mistake. >> Or maybe they were influenced by Python round, but should have checked >> how it is implemented: >> For example, see >> https://github.com/python/cpython/blob/c7688b44387d116522ff53c0927169db45969f0e/Python/pymath.c >> >> double round(double x) { double absx, y; absx = fabs(x); y = floor(absx); >> if (absx - y >= 0.5) y += 1.0; return copysign(y, x); } >> > > Oups, that's round without argument... > > It is rather in https://github.com/python/cpython/blob/12f02a041ecca16d61352548dc4573095f0dae10/Objects/floatobject.c And it is using dtoa, that is equivalent to ^(Float readFrom: (self printShowingDecimalPlaces: n) readStream) > >> That should translate easily in Smalltalk if REALLY necessary... >> >> >> You're right about the printing thing in Artefact. I replaced #round: >>> with #printOn:maxDecimalPlaces: in my image. >>> >>> >> Easy to guess, the only other possible use I can think of, is naive >> monetary apps; that makes two reasons to ban the message ;) >> >> >> >> Levente >>> >>> >>>> Nicolas >>>> >>>> >>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150502/c86fe67f/attachment-0001.htm From commits at source.squeak.org Sat May 2 21:55:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 2 21:55:05 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150502215503.4410.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008216.html Name: Morphic-mt.957 Ancestors: Morphic-mt.956 Allow models to trigger accept/revert changes in pluggable text morphs. Why? Provides an additional, more general way besides context menus or keyboard shortcuts. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008217.html Name: MorphicTests-mt.30 Ancestors: MorphicTests-mt.29 Tests added for pluggable text morphs. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008218.html Name: ShoutCore-ul.48 Ancestors: ShoutCore-ul.47 SHMCClassDefinition changes: - Implemented the missing #withAllSuperclassesDo: - #withAllSuperclasses uses #withAllSuperclassesDo:, and returns an OrderedCollection with the classes in the same order as in Behavior's implementation. - Recategorized some methods. Use #withAllSuperclassesDo: instead of #withAllSuperclasses in all methods of SHParserST80. Updated TextAction >> #shoutShouldPreserve to reflect the original intention - preserve all TextAction attributes. Slightly faster SHTextStylerST80 >> #setAttributesIn:fromRanges:. Removed the now useless SHTextStylerST80 >> #shouldPreserveAttribute:. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008219.html Name: Morphic-kfr.958 Ancestors: Morphic-mt.957 Couple of layout and color fixes to NewColorPickerMorph ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008220.html Name: Morphic-kfr.959 Ancestors: Morphic-kfr.958 Added back drop shadow preference ============================================= From nicolas.cellier.aka.nice at gmail.com Sat May 2 23:42:24 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sat May 2 23:42:25 2015 Subject: [squeak-dev] Slider trimValue: vs trimmedValue: Message-ID: They sound much too similar and it seems that the first is not sent... Cleanup welcomed... Nicolas -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150503/788f05fc/attachment.htm From commits at source.squeak.org Sun May 3 00:15:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 00:15:45 2015 Subject: [squeak-dev] The Trunk: Multilingual-ul.209.mcz Message-ID: Levente Uzonyi uploaded a new version of Multilingual to project The Trunk: http://source.squeak.org/trunk/Multilingual-ul.209.mcz ==================== Summary ==================== Name: Multilingual-ul.209 Author: ul Time: 1 May 2015, 7:48:22.654 pm UUID: 966caead-fd54-4687-9369-3580c258e5db Ancestors: Multilingual-ul.208 Refactored unicode data parsing. Case conversion (ToUpper and ToLower) is parsed from UnicodeData.txt instead of CaseFolding.txt. Reinitialize both CaseFolding and CompositionMapping in the postscript. =============== Diff against Multilingual-ul.206 =============== Item was added: + ----- Method: Unicode class>>caseFoldingData (in category 'casing') ----- + caseFoldingData + + UIManager default informUserDuring: [ :bar | + | stream | + bar value: 'Downloading CaseFolding Unicode data'. + stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/CaseFolding.txt'. + (stream isKindOf: RWBinaryOrTextStream) ifFalse: [ + ^self error: 'Download failed' ]. + ^stream reset; contents ]! Item was added: + ----- Method: Unicode class>>initializeCaseFolding (in category 'casing') ----- + initializeCaseFolding + " self initializeCaseFolding " + + self parseCaseFoldingFrom: self caseFoldingData! Item was removed: - ----- Method: Unicode class>>initializeCaseMappings (in category 'casing') ----- - initializeCaseMappings - "Unicode initializeCaseMappings" - ToCasefold := IdentityDictionary new. - ToUpper := IdentityDictionary new. - ToLower := IdentityDictionary new. - UIManager default informUserDuring: [:bar| - | stream | - bar value: 'Downloading Unicode data'. - stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/CaseFolding.txt'. - (stream isKindOf: RWBinaryOrTextStream) ifFalse:[^self error: 'Download failed']. - stream reset. - bar value: 'Updating Case Mappings'. - self parseCaseMappingFrom: stream. - ].! Item was changed: ----- Method: Unicode class>>initializeCompositionMappings (in category 'composing') ----- initializeCompositionMappings + " self initializeCompositionMappings " + + self parseCompositionMappingFrom: self unicodeData! - "Unicode initializeCompositionMappings" - Compositions := IdentityDictionary new. - Decompositions := IdentityDictionary new. - UIManager default informUserDuring:[:bar| - | stream | - bar value: 'Downloading Unicode data'. - stream := HTTPClient httpGet: 'http://unicode.org/Public/UNIDATA/UnicodeData.txt'. - (stream isKindOf: RWBinaryOrTextStream) ifFalse:[^self error: 'Download failed']. - stream reset. - bar value: 'Updating Composition Mappings'. - self parseCompositionMappingFrom: stream. - ].! Item was added: + ----- Method: Unicode class>>parseCaseFoldingFrom: (in category 'casing') ----- + parseCaseFoldingFrom: caseFoldingData + "Parse the Unicode casing mappings from the given string." + + | newToCasefold | + newToCasefold := PluggableDictionary integerDictionary. + + "Filter the mappings (Simple and Common) to newToCasefold." + caseFoldingData linesDo: [ :line | + | lineWithoutComment fields sourceCode destinationCode | + lineWithoutComment := line copyUpTo: $#. + fields := lineWithoutComment findTokens: '; '. + (fields size > 2 and: [ #('C' 'S') includes: (fields at: 2) ]) ifTrue: [ + sourceCode := Integer readFrom: (fields at: 1) base: 16. + destinationCode := Integer readFrom: (fields at: 3) base: 16. + newToCasefold at: sourceCode put: destinationCode ] ]. + + "Compact and save." + ToCasefold := newToCasefold compact + ! Item was removed: - ----- Method: Unicode class>>parseCaseMappingFrom: (in category 'casing') ----- - parseCaseMappingFrom: stream - "Parse the Unicode casing mappings from the given stream. - Handle only the simple mappings" - " - Unicode initializeCaseMappings. - " - - ToCasefold := IdentityDictionary new: 2048. - ToUpper := IdentityDictionary new: 2048. - ToLower := IdentityDictionary new: 2048. - - [stream atEnd] whileFalse:[ - | fields line srcCode dstCode | - line := stream nextLine copyUpTo: $#. - fields := line withBlanksTrimmed findTokens: $;. - (fields size > 2 and: [#('C' 'S') includes: (fields at: 2) withBlanksTrimmed]) ifTrue:[ - srcCode := Integer readFrom: (fields at: 1) withBlanksTrimmed base: 16. - dstCode := Integer readFrom: (fields at: 3) withBlanksTrimmed base: 16. - ToCasefold at: srcCode put: dstCode. - ]. - ]. - - ToCasefold keysAndValuesDo: - [:k :v | - (self isUppercaseCode: k) - ifTrue: - ["In most cases, uppercase letter are folded to lower case" - ToUpper at: v put: k. - ToLower at: k put: v]. - (self isLowercaseCode: k) - ifTrue: - ["In a few cases, two upper case letters are folded to the same lower case. - We must find an upper case letter folded to the same letter" - | up | - up := ToCasefold keys detect: [:e | (self isUppercaseCode: e) and: [(ToCasefold at: e) = v]] ifNone: [nil]. - up ifNotNil: [ToUpper at: k put: up]]].! Item was changed: ----- Method: Unicode class>>parseCompositionMappingFrom: (in category 'composing') ----- + parseCompositionMappingFrom: unicodeData - parseCompositionMappingFrom: stream "Parse the Unicode composition mappings from the given stream" " Unicode initializeCompositionMappings. " + | newCompositions newDecompositions newToUpper newToLower toNumber | - | toNumber fields codePoint decomposed baseChar compChar line | toNumber := [:quad | quad inject: 0 into:[:sum :ch| sum * 16 + ch digitValue]]. + newCompositions := PluggableDictionary integerDictionary. + newDecompositions := PluggableDictionary integerDictionary. + newToUpper := PluggableDictionary integerDictionary. + newToLower := PluggableDictionary integerDictionary. - Compositions := IdentityDictionary new: 2048. - Decompositions := IdentityDictionary new: 2048. + unicodeData linesDo: [ :line | + | fields | + (fields := line splitBy: ';') size > 13 ifTrue: [ + | codePoint lowercaseCodePoint uppercaseCodePoint decomposed baseChar compChar | - [stream atEnd] whileFalse:[ - line := (stream nextLine copyUpTo: $#) withBlanksTrimmed readStream. - fields := Array streamContents:[:s|[line atEnd] whileFalse:[s nextPut: (line upTo: $;)]]. - fields size > 6 ifTrue:[ codePoint := toNumber value: (fields at: 1). + uppercaseCodePoint := (fields at: 13) ifEmpty: [ codePoint ] ifNotEmpty: toNumber. + codePoint = uppercaseCodePoint ifFalse: [ newToUpper at: codePoint put: uppercaseCodePoint ]. + lowercaseCodePoint := (fields at: 14) ifEmpty: [ codePoint ] ifNotEmpty: toNumber. + codePoint = lowercaseCodePoint ifFalse: [ newToLower at: codePoint put: lowercaseCodePoint ]. decomposed := (fields at: 6) findTokens: ' '. (decomposed size = 2 and:[decomposed first first ~= $<]) ifTrue:[ + decomposed replace: toNumber. - decomposed := decomposed collect: toNumber. baseChar := decomposed first. "base character" compChar := decomposed second. "composition character" + newDecompositions at: codePoint put: { baseChar. compChar }. + (newCompositions at: baseChar ifAbsentPut: [ PluggableDictionary integerDictionary ]) + at: compChar put: codePoint ] ] ]. + + "Compact the new dictionaries." + newCompositions compact. + newCompositions valuesDo: [ :each | each compact ]. + newDecompositions compact. + newToUpper compact. + newToLower compact. + "Save atomically." + Compositions := newCompositions. + Decompositions := newDecompositions. + ToUpper := newToUpper. + ToLower := newToLower. - Decompositions at: codePoint put: (Array with: baseChar with: compChar). - (Compositions at: baseChar ifAbsentPut:[IdentityDictionary new]) - at: compChar put: codePoint. - ]. - ]. - ]. ! Item was added: + ----- Method: Unicode class>>unicodeData (in category 'composing') ----- + unicodeData + + UIManager default informUserDuring: [ :bar | + | stream | + bar value: 'Downloading Unicode data'. + stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/UnicodeData.txt'. + (stream isKindOf: RWBinaryOrTextStream) ifFalse: [ + ^self error: 'Download failed' ]. + ^stream reset; contents ]! Item was changed: + (PackageInfo named: 'Multilingual') postscript: 'Unicode + initializeCaseFolding; + initializeCompositionMappings'! - (PackageInfo named: 'Multilingual') postscript: '"Remove CrLfFileStream from the startupList" - (Smalltalk classNamed: ''CrLfFileStream'') ifNotNil: [ :class | - Smalltalk removeFromStartUpList: class ]. - "Ensure toLower et al work on WideStrings" - Unicode - initialize; - initializeCaseMappings. - '! From commits at source.squeak.org Sun May 3 00:16:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 00:16:01 2015 Subject: [squeak-dev] The Trunk: Multilingual-ul.208.mcz Message-ID: Levente Uzonyi uploaded a new version of Multilingual to project The Trunk: http://source.squeak.org/trunk/Multilingual-ul.208.mcz ==================== Summary ==================== Name: Multilingual-ul.208 Author: ul Time: 1 May 2015, 3:25:18.828 pm UUID: 82d19dac-c602-4c0d-bc9a-7858e3a3c283 Ancestors: Multilingual-ul.206 Improved Unicode caseMappings: - Don't overwrite an existing mapping, because that leads to problems (like (Unicode toUppercaseCode: $k asciiValue) = 8490) - Use PluggableDictionary class >> #integerDictionary for better lookup performance (~+16%), and compaction resistance (done at every release). - Compact the dictionaries before saving. - Save the new dictionaries atomically. =============== Diff against Multilingual-ul.206 =============== Item was changed: ----- Method: Unicode class>>initializeCaseMappings (in category 'casing') ----- initializeCaseMappings "Unicode initializeCaseMappings" + + UIManager default informUserDuring: [ :bar | - ToCasefold := IdentityDictionary new. - ToUpper := IdentityDictionary new. - ToLower := IdentityDictionary new. - UIManager default informUserDuring: [:bar| | stream | bar value: 'Downloading Unicode data'. stream := HTTPClient httpGet: 'http://www.unicode.org/Public/UNIDATA/CaseFolding.txt'. (stream isKindOf: RWBinaryOrTextStream) ifFalse:[^self error: 'Download failed']. stream reset. bar value: 'Updating Case Mappings'. + self parseCaseMappingFrom: stream ].! - self parseCaseMappingFrom: stream. - ].! Item was changed: ----- Method: Unicode class>>parseCaseMappingFrom: (in category 'casing') ----- parseCaseMappingFrom: stream "Parse the Unicode casing mappings from the given stream. Handle only the simple mappings" " Unicode initializeCaseMappings. " + | newToCasefold newToUpper newToLower casefoldKeys | + newToCasefold := PluggableDictionary integerDictionary. + newToUpper := PluggableDictionary integerDictionary. + newToLower := PluggableDictionary integerDictionary. - ToCasefold := IdentityDictionary new: 2048. - ToUpper := IdentityDictionary new: 2048. - ToLower := IdentityDictionary new: 2048. + "Filter the mappings (Simple and Common) to newToCasefold." + stream contents linesDo: [ :line | + | data fields sourceCode destinationCode | + data := line copyUpTo: $#. + fields := data findTokens: '; '. + (fields size > 2 and: [ #('C' 'S') includes: (fields at: 2) ]) ifTrue:[ + sourceCode := Integer readFrom: (fields at: 1) base: 16. + destinationCode := Integer readFrom: (fields at: 3) base: 16. + newToCasefold at: sourceCode put: destinationCode ] ]. - [stream atEnd] whileFalse:[ - | fields line srcCode dstCode | - line := stream nextLine copyUpTo: $#. - fields := line withBlanksTrimmed findTokens: $;. - (fields size > 2 and: [#('C' 'S') includes: (fields at: 2) withBlanksTrimmed]) ifTrue:[ - srcCode := Integer readFrom: (fields at: 1) withBlanksTrimmed base: 16. - dstCode := Integer readFrom: (fields at: 3) withBlanksTrimmed base: 16. - ToCasefold at: srcCode put: dstCode. - ]. - ]. + casefoldKeys := newToCasefold keys. + newToCasefold keysAndValuesDo: [ :sourceCode :destinationCode | + (self isUppercaseCode: sourceCode) ifTrue: [ + "In most cases, uppercase letter are folded to lower case" + newToUpper at: destinationCode put: sourceCode. + newToLower at: sourceCode ifAbsentPut: destinationCode "Don't overwrite existing pairs. To avoid $k asUppercase to return the Kelvin character (8490)." ]. + (self isLowercaseCode: sourceCode) ifTrue: [ + "In a few cases, two upper case letters are folded to the same lower case. + We must find an upper case letter folded to the same letter" + casefoldKeys + detect: [ :each | + (self isUppercaseCode: each) and: [ + (newToCasefold at: each) = destinationCode ] ] + ifFound: [ :uppercaseCode | + newToUpper at: sourceCode put: uppercaseCode ] + ifNone: [ ] ] ]. + + "Compact the dictionaries." + newToCasefold compact. + newToUpper compact. + newToLower compact. + "Save in an atomic operation." + ToCasefold := newToCasefold. + ToUpper := newToUpper. + ToLower := newToLower + ! - ToCasefold keysAndValuesDo: - [:k :v | - (self isUppercaseCode: k) - ifTrue: - ["In most cases, uppercase letter are folded to lower case" - ToUpper at: v put: k. - ToLower at: k put: v]. - (self isLowercaseCode: k) - ifTrue: - ["In a few cases, two upper case letters are folded to the same lower case. - We must find an upper case letter folded to the same letter" - | up | - up := ToCasefold keys detect: [:e | (self isUppercaseCode: e) and: [(ToCasefold at: e) = v]] ifNone: [nil]. - up ifNotNil: [ToUpper at: k put: up]]].! From commits at source.squeak.org Sun May 3 00:17:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 00:17:13 2015 Subject: [squeak-dev] The Trunk: MorphicExtras-nice.163.mcz Message-ID: Nicolas Cellier uploaded a new version of MorphicExtras to project The Trunk: http://source.squeak.org/trunk/MorphicExtras-nice.163.mcz ==================== Summary ==================== Name: MorphicExtras-nice.163 Author: nice Time: 3 May 2015, 2:16:38.03 am UUID: 438a6829-eb6d-4c46-974a-e37c91919765 Ancestors: MorphicExtras-mt.162 Avoid using roundTo: aFloat if it's just for printing. Why? (0.3 roundTo: 0.1) printString -> '0.30000000000000004' =============== Diff against MorphicExtras-mt.162 =============== Item was changed: ----- Method: WaveEditor>>chooseLoopStart (in category 'menu') ----- chooseLoopStart | bestLoops choice start labels values | possibleLoopStarts ifNil: [ UIManager default informUser: 'Finding possible loop points...' translated during: [possibleLoopStarts := self findPossibleLoopStartsFrom: graph cursor]]. bestLoops := possibleLoopStarts copyFrom: 1 to: (100 min: possibleLoopStarts size). labels := OrderedCollection new. values := OrderedCollection new. bestLoops do: [:entry | | secs | + secs := ((loopEnd - entry first) asFloat / self samplingRate) printShowingMaxDecimalPlaces: 2. - secs := ((loopEnd - entry first) asFloat / self samplingRate) roundTo: 0.01. labels add: ('{1} cycles; {2} secs' translated format:{entry third. secs}). values add: entry]. choice := UIManager default chooseFrom: labels values: values. choice ifNil: [^ self]. loopCycles := choice third. start := self fractionalLoopStartAt: choice first. self loopLength: (loopEnd asFloat - start) + 1.0. ! From nicolas.cellier.aka.nice at gmail.com Sun May 3 01:29:14 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Sun May 3 01:29:16 2015 Subject: [squeak-dev] The Trunk: Multilingual-ul.208.mcz In-Reply-To: <554568c5.ea0a340a.23fb.6268SMTPIN_ADDED_MISSING@mx.google.com> References: <554568c5.ea0a340a.23fb.6268SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Ouch, yes, extracting simple case mapping from full CaseFolding data was probably a mistake... Thanks for reviewing, and as we say, vieux motard que jamais (better late than never) - it's almost 5 years old Next job will be to comment Unicode class, and explain which unicode operation is supported... -------------------------- Multilingual-nice.123 Author: nice Time: 14 July 2010, 1:17:02.219 pm UUID: ec8f05b8-78a6-4496-aca9-8f9b2e54823d Ancestors: Multilingual-ul.122 1) simplify a case of at:ifAbsentPut: pattern in SparseXTable 2) provide a simple mapping of unicode upper/lower case characters as described at http://unicode.org/reports/tr21/tr21-5.html Note 1: Unicode class now provides two utilities to transform case of a String rather than of a Character. This is for enabling future enhancements like handling special casings when case folding does change the number of characters. Note 2: there is no automatic initialization performed yet. You'll have to execute this before using above utilities: Unicode initializeCaseMappings. This is only an unoptimized, first attempt proposal. Comments and changes are of course welcome. 2015-05-03 2:15 GMT+02:00 : > Levente Uzonyi uploaded a new version of Multilingual to project The Trunk: > http://source.squeak.org/trunk/Multilingual-ul.208.mcz > > ==================== Summary ==================== > > Name: Multilingual-ul.208 > Author: ul > Time: 1 May 2015, 3:25:18.828 pm > UUID: 82d19dac-c602-4c0d-bc9a-7858e3a3c283 > Ancestors: Multilingual-ul.206 > > Improved Unicode caseMappings: > - Don't overwrite an existing mapping, because that leads to problems > (like (Unicode toUppercaseCode: $k asciiValue) = 8490) > - Use PluggableDictionary class >> #integerDictionary for better lookup > performance (~+16%), and compaction resistance (done at every release). > - Compact the dictionaries before saving. > - Save the new dictionaries atomically. > > =============== Diff against Multilingual-ul.206 =============== > > Item was changed: > ----- Method: Unicode class>>initializeCaseMappings (in category > 'casing') ----- > initializeCaseMappings > "Unicode initializeCaseMappings" > + > + UIManager default informUserDuring: [ :bar | > - ToCasefold := IdentityDictionary new. > - ToUpper := IdentityDictionary new. > - ToLower := IdentityDictionary new. > - UIManager default informUserDuring: [:bar| > | stream | > bar value: 'Downloading Unicode data'. > stream := HTTPClient httpGet: ' > http://www.unicode.org/Public/UNIDATA/CaseFolding.txt'. > (stream isKindOf: RWBinaryOrTextStream) ifFalse:[^self > error: 'Download failed']. > stream reset. > bar value: 'Updating Case Mappings'. > + self parseCaseMappingFrom: stream ].! > - self parseCaseMappingFrom: stream. > - ].! > > Item was changed: > ----- Method: Unicode class>>parseCaseMappingFrom: (in category > 'casing') ----- > parseCaseMappingFrom: stream > "Parse the Unicode casing mappings from the given stream. > Handle only the simple mappings" > " > Unicode initializeCaseMappings. > " > > + | newToCasefold newToUpper newToLower casefoldKeys | > + newToCasefold := PluggableDictionary integerDictionary. > + newToUpper := PluggableDictionary integerDictionary. > + newToLower := PluggableDictionary integerDictionary. > - ToCasefold := IdentityDictionary new: 2048. > - ToUpper := IdentityDictionary new: 2048. > - ToLower := IdentityDictionary new: 2048. > > + "Filter the mappings (Simple and Common) to newToCasefold." > + stream contents linesDo: [ :line | > + | data fields sourceCode destinationCode | > + data := line copyUpTo: $#. > + fields := data findTokens: '; '. > + (fields size > 2 and: [ #('C' 'S') includes: (fields at: > 2) ]) ifTrue:[ > + sourceCode := Integer readFrom: (fields at: 1) > base: 16. > + destinationCode := Integer readFrom: (fields at: > 3) base: 16. > + newToCasefold at: sourceCode put: destinationCode > ] ]. > - [stream atEnd] whileFalse:[ > - | fields line srcCode dstCode | > - line := stream nextLine copyUpTo: $#. > - fields := line withBlanksTrimmed findTokens: $;. > - (fields size > 2 and: [#('C' 'S') includes: (fields at: 2) > withBlanksTrimmed]) ifTrue:[ > - srcCode := Integer readFrom: (fields at: 1) > withBlanksTrimmed base: 16. > - dstCode := Integer readFrom: (fields at: 3) > withBlanksTrimmed base: 16. > - ToCasefold at: srcCode put: dstCode. > - ]. > - ]. > > + casefoldKeys := newToCasefold keys. > + newToCasefold keysAndValuesDo: [ :sourceCode :destinationCode | > + (self isUppercaseCode: sourceCode) ifTrue: [ > + "In most cases, uppercase letter are folded to > lower case" > + newToUpper at: destinationCode put: sourceCode. > + newToLower at: sourceCode ifAbsentPut: > destinationCode "Don't overwrite existing pairs. To avoid $k asUppercase to > return the Kelvin character (8490)." ]. > + (self isLowercaseCode: sourceCode) ifTrue: [ > + "In a few cases, two upper case letters are folded > to the same lower case. > + We must find an upper case letter folded to the > same letter" > + casefoldKeys > + detect: [ :each | > + (self isUppercaseCode: each) and: [ > + (newToCasefold at: each) = > destinationCode ] ] > + ifFound: [ :uppercaseCode | > + newToUpper at: sourceCode put: > uppercaseCode ] > + ifNone: [ ] ] ]. > + > + "Compact the dictionaries." > + newToCasefold compact. > + newToUpper compact. > + newToLower compact. > + "Save in an atomic operation." > + ToCasefold := newToCasefold. > + ToUpper := newToUpper. > + ToLower := newToLower > + ! > - ToCasefold keysAndValuesDo: > - [:k :v | > - (self isUppercaseCode: k) > - ifTrue: > - ["In most cases, uppercase letter are > folded to lower case" > - ToUpper at: v put: k. > - ToLower at: k put: v]. > - (self isLowercaseCode: k) > - ifTrue: > - ["In a few cases, two upper case letters > are folded to the same lower case. > - We must find an upper case letter folded > to the same letter" > - | up | > - up := ToCasefold keys detect: [:e | (self > isUppercaseCode: e) and: [(ToCasefold at: e) = v]] ifNone: [nil]. > - up ifNotNil: [ToUpper at: k put: up]]].! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150503/91226eab/attachment.htm From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 06:27:51 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 06:43:15 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> Message-ID: <1430634471479-4823901.post@n4.nabble.com> Scattering is not a big deal here. Senders of those pragmas will find them all. However, It is quite impeding to attach those pragma preferences -- is most cases -- to Morph classes. MVC tools don't get configurable at all... :-/ We should move those preferences to the class-side of ToolBuilder's spec classes. In the concrete builder classes, we could store project-specific migration code for preference changes. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823901.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Sun May 3 06:59:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 06:59:31 2015 Subject: [squeak-dev] The Trunk: Tools-mt.616.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.616.mcz ==================== Summary ==================== Name: Tools-mt.616 Author: mt Time: 3 May 2015, 8:59:08.565 am UUID: d7973151-c795-fb4c-9d1f-daab9ef068e6 Ancestors: Tools-mt.615 Fixed wrong order of buttons in pre-debug window. =============== Diff against Tools-mt.615 =============== Item was changed: ----- Method: Debugger>>buildNotifierWith:label:message: (in category 'toolbuilder') ----- buildNotifierWith: builder label: label message: messageString | windowSpec listSpec textSpec panelSpec quads | windowSpec := builder pluggableWindowSpec new model: self; extent: self initialExtentForNotifier; label: label; children: OrderedCollection new. panelSpec := builder pluggablePanelSpec new. panelSpec children: OrderedCollection new. quads := self preDebugButtonQuads. (self interruptedContext selector == #doesNotUnderstand:) ifTrue: [ quads := quads copyWith: { 'Create'. #createMethod. #magenta. 'create the missing method' } ]. (#(#notYetImplemented #shouldBeImplemented #requirement) includes: self interruptedContext selector) ifTrue: [ quads := quads copyWith: { 'Create'. #createImplementingMethod. #magenta. 'implement the marked method' } ]. (self interruptedContext selector == #subclassResponsibility) ifTrue: [ quads := quads copyWith: { 'Create'. #createOverridingMethod. #magenta. 'create the missing overriding method' } ]. quads do:[:spec| | buttonSpec | buttonSpec := builder pluggableButtonSpec new. buttonSpec model: self. buttonSpec label: spec first. buttonSpec action: spec second. buttonSpec help: spec fourth. - buttonSpec frame: self preDebugButtonQuadFrame. panelSpec children add: buttonSpec. ]. panelSpec layout: #horizontal. "buttons" panelSpec frame: self preDebugButtonQuadFrame. windowSpec children add: panelSpec. Preferences eToyFriendly | messageString notNil ifFalse:[ listSpec := builder pluggableListSpec new. listSpec model: self; list: #contextStackList; getIndex: #contextStackIndex; setIndex: #debugAt:; frame: self contextStackFrame. windowSpec children add: listSpec. ] ifTrue:[ message := messageString. textSpec := builder pluggableTextSpec new. textSpec model: self; getText: #preDebugMessageString; setText: nil; selection: nil; menu: #debugProceedMenu:; frame: self contextStackFrame. windowSpec children add: textSpec. ]. ^windowSpec! From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 06:48:27 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 07:03:52 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: <1430634471479-4823901.post@n4.nabble.com> References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> Message-ID: <1430635707869-4823904.post@n4.nabble.com> ...but if we want to let Morphs access those preferences, we probably still need such a class-side abstraction in Morphs. Otherwise Morphic would be dependent on Tools, which should not be. Such preference access happens in Morphs in many places right now. Even outside initialization code, which is not good because a single morph cannot behave differently to the system's preferences easily. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823904.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 06:51:17 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 07:06:41 2015 Subject: [squeak-dev] Re: pre-debugger buttons are backward In-Reply-To: References: Message-ID: <1430635877197-4823905.post@n4.nabble.com> Fixed: http://forum.world.st/The-Trunk-Tools-mt-616-mcz-td4823903.html Somehow, each of the buttons got a layout frame, which is nowadays a trigger in the tool builder to not care about the insertion order because that order should be encoded in the particular layout frame. :) Best, Marcel -- View this message in context: http://forum.world.st/pre-debugger-buttons-are-backward-tp4823845p4823905.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Sun May 3 07:09:38 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 07:09:41 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.960.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.960.mcz ==================== Summary ==================== Name: Morphic-mt.960 Author: mt Time: 3 May 2015, 9:08:58.933 am UUID: 3fcff502-3aa6-d34f-87ce-fa23e09fe5c0 Ancestors: Morphic-kfr.959 Dead code removed from slider. =============== Diff against Morphic-kfr.959 =============== Item was removed: - ----- Method: Slider>>trimValue: (in category 'support') ----- - trimValue: aValue - - | trimmedValue | - trimmedValue := aValue min: self maximumValue max: self minimumValue. - self quantum ifNotNil: [:q | trimmedValue := trimmedValue roundTo: q]. - ^ trimmedValue - ! From commits at source.squeak.org Sun May 3 08:32:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 08:32:09 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Kernel-mt.87.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Kernel to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Kernel-mt.87.mcz ==================== Summary ==================== Name: ToolBuilder-Kernel-mt.87 Author: mt Time: 3 May 2015, 10:32:01.168 am UUID: 25617b43-37ef-f741-9f9f-249adcb3ee77 Ancestors: ToolBuilder-Kernel-mt.86 Added resizing policies to layout hints. =============== Diff against ToolBuilder-Kernel-mt.86 =============== Item was changed: ToolBuilderSpec subclass: #PluggableWidgetSpec + instanceVariableNames: 'model frame color minimumExtent margin padding horizontalResizing verticalResizing' - instanceVariableNames: 'model frame color minimumExtent margin padding' classVariableNames: '' poolDictionaries: '' category: 'ToolBuilder-Kernel'! !PluggableWidgetSpec commentStamp: 'ar 2/9/2005 18:40' prior: 0! The abstract superclass for all widgets. Instance variables: model The object the various requests should be directed to. frame The associated layout frame for this object (if any). ! Item was added: + ----- Method: PluggableWidgetSpec>>horizontalResizing (in category 'layout hints') ----- + horizontalResizing + + ^ horizontalResizing! Item was added: + ----- Method: PluggableWidgetSpec>>horizontalResizing: (in category 'layout hints') ----- + horizontalResizing: aSymbol + "#rigid, #spaceFill, #shrinkWrap" + + horizontalResizing := aSymbol.! Item was added: + ----- Method: PluggableWidgetSpec>>verticalResizing (in category 'layout hints') ----- + verticalResizing + + ^ verticalResizing! Item was added: + ----- Method: PluggableWidgetSpec>>verticalResizing: (in category 'layout hints') ----- + verticalResizing: aSymbol + "#rigid, #spaceFill, #shrinkWrap" + + verticalResizing := aSymbol.! From commits at source.squeak.org Sun May 3 08:34:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 08:34:28 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Morphic-mt.143.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.143.mcz ==================== Summary ==================== Name: ToolBuilder-Morphic-mt.143 Author: mt Time: 3 May 2015, 10:34:22.75 am UUID: 4ee679ac-c35a-7b4d-80eb-b138d4d84702 Ancestors: ToolBuilder-Morphic-mt.142 Honor custom resizing policies. =============== Diff against ToolBuilder-Morphic-mt.142 =============== Item was changed: ----- Method: MorphicToolBuilder>>buildPluggablePanel: (in category 'widgets required') ----- buildPluggablePanel: aSpec | widget | widget := self panelClass new. self register: widget id: aSpec name. widget model: aSpec model. "Set child dependent layout properties." widget wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [false]). + self setLayoutHintsFor: widget spec: aSpec. widget layoutInset: (aSpec padding ifNil: [0]). widget cellInset: (aSpec spacing ifNil: [ widget wantsPaneSplitters ifTrue: [ProportionalSplitterMorph gripThickness] ifFalse: [2]]). "Now create the children." aSpec children isSymbol ifTrue: [ widget getChildrenSelector: aSpec children. widget update: aSpec children] ifFalse: [ self buildAll: aSpec children in: widget]. self setFrame: aSpec frame in: widget. self setLayout: aSpec layout in: widget. - self setLayoutHintsFor: widget spec: aSpec. parent ifNotNil:[self add: widget to: parent]. widget borderWidth: 0. self buildHelpFor: widget spec: aSpec. widget color: Color transparent. ^ widget! Item was changed: ----- Method: MorphicToolBuilder>>buildPluggableWindow: (in category 'widgets required') ----- buildPluggableWindow: aSpec | widget | aSpec layout == #proportional ifFalse:[ "This needs to be implemented - probably by adding a single pane and then the rest" ^self error: 'Not implemented'. ]. widget := (self windowClassFor: aSpec) new. self register: widget id: aSpec name. widget model: aSpec model. "Set child dependent layout properties." widget wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [true]). + self setLayoutHintsFor: widget spec: aSpec. widget layoutInset: (aSpec padding ifNil: [ProportionalSplitterMorph gripThickness]). widget cellInset: (aSpec spacing ifNil: [ProportionalSplitterMorph gripThickness]). "Now create the children." panes := OrderedCollection new. aSpec children isSymbol ifTrue: [ widget getChildrenSelector: aSpec children. widget update: aSpec children] ifFalse: [ self buildAll: aSpec children in: widget]. widget setUpdatablePanesFrom: panes. aSpec label ifNotNil: [:label| label isSymbol ifTrue:[widget getLabelSelector: label] ifFalse:[widget setLabel: label]]. aSpec multiWindowStyle notNil ifTrue: [widget savedMultiWindowState: (SavedMultiWindowState on: aSpec model)]. widget closeWindowSelector: aSpec closeAction. self buildHelpFor: widget spec: aSpec. widget bounds: (RealEstateAgent initialFrameFor: widget initialExtent: (aSpec extent ifNil:[widget initialExtent]) world: self currentWorld). - self setLayoutHintsFor: widget spec: aSpec. ^ widget! Item was changed: ----- Method: MorphicToolBuilder>>setLayout:in: (in category 'private') ----- setLayout: layout in: widget layout == #proportional ifTrue:[ widget layoutPolicy: ProportionalLayout new. ^self]. layout == #horizontal ifTrue:[ widget layoutPolicy: TableLayout new. widget listDirection: #leftToRight. - widget submorphsDo:[:m| m hResizing: #spaceFill; vResizing: #spaceFill]. "widget cellInset: 1@1. widget layoutInset: 1@1." widget color: Color transparent. "and then some..." ^self]. layout == #vertical ifTrue:[ widget layoutPolicy: TableLayout new. widget listDirection: #topToBottom. - widget submorphsDo:[:m| m hResizing: #spaceFill; vResizing: #spaceFill]. "widget cellInset: 1@1. widget layoutInset: 1@1." widget color: Color transparent. "and then some..." ^self]. ^self error: 'Unknown layout: ', layout.! Item was changed: ----- Method: MorphicToolBuilder>>setLayoutHintsFor:spec: (in category 'private') ----- setLayoutHintsFor: widget spec: aSpec aSpec minimumWidth >= 0 ifTrue: [widget minimumWidth: aSpec minimumWidth]. aSpec minimumHeight >= 0 + ifTrue: [widget minimumHeight: aSpec minimumHeight]. + aSpec padding + ifNotNil: [:p | widget layoutInset: p]. + "aSpec margin + ifNotNil: [:m | widget layoutOutset: m]." + + widget hResizing: (aSpec horizontalResizing ifNil: [#spaceFill]). + widget vResizing: (aSpec verticalResizing ifNil: [#spaceFill]).! - ifTrue: [widget minimumHeight: aSpec minimumHeight].! From commits at source.squeak.org Sun May 3 08:36:36 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 08:36:39 2015 Subject: [squeak-dev] The Trunk: Kernel-mt.924.mcz Message-ID: Marcel Taeumel uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.924.mcz ==================== Summary ==================== Name: Kernel-mt.924 Author: mt Time: 3 May 2015, 10:36:03.973 am UUID: f9df7cdb-eb50-f54a-b1a5-8fcd565313b7 Ancestors: Kernel-nice.923 ValueHolder: Only notify about changed contents if contents actually changed. =============== Diff against Kernel-nice.923 =============== Item was changed: ----- Method: ValueHolder>>contents: (in category 'accessing') ----- contents: newContents + + contents = newContents ifTrue: [^ self]. contents := newContents. self contentsChanged! From commits at source.squeak.org Sun May 3 08:38:31 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 08:38:32 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.961.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.961.mcz ==================== Summary ==================== Name: Morphic-mt.961 Author: mt Time: 3 May 2015, 10:37:41.57 am UUID: 9d90662f-0ca8-be4f-955b-15ceef53104b Ancestors: Morphic-mt.960 Fixed shrinkWrap-bug in buttons. =============== Diff against Morphic-mt.960 =============== Item was changed: ----- Method: PluggableButtonMorph>>updateMinimumExtent (in category 'layout') ----- updateMinimumExtent | hMin vMin | self label isMorph ifTrue: [^ self minimumExtent: self label minExtent]. hMin := vMin := 16. self hResizing == #shrinkWrap ifTrue: [hMin := (self font widthOfString: self label) max: self labelShrinkThreshold]. self vResizing == #shrinkWrap ifTrue: [vMin := self font height]. + + hMin := hMin + (2* self borderStyle width). + vMin := vMin + (2* self borderStyle width). self layoutInset isRectangle ifTrue: [ hMin := hMin + self layoutInset left + self layoutInset right. vMin := vMin + self layoutInset top + self layoutInset bottom] ifFalse: [self layoutInset isPoint ifTrue: [ hMin := hMin + (2* self layoutInset x). vMin := vMin + (2* self layoutInset y)] ifFalse: [ hMin := hMin + (2* self layoutInset). vMin := vMin + (2* self layoutInset)]]. + self minimumExtent: hMin @ vMin. + + "Since we have no submorphs, we have to resize here if we want to shrink wrap." + self hResizing == #shrinkWrap ifTrue: [self width: hMin]. + self vResizing == #shrinkWrap ifTrue: [self height: vMin].! - self minimumExtent: hMin @ vMin! From commits at source.squeak.org Sun May 3 08:57:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 08:57:06 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.962.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.962.mcz ==================== Summary ==================== Name: Morphic-mt.962 Author: mt Time: 3 May 2015, 10:56:28.091 am UUID: 7e9a02a2-169b-9d44-8450-3e0074dead2c Ancestors: Morphic-mt.961 Never share the text instance between text morph and model. Change handling can break otherwise if that text instance will be referenced in the model. =============== Diff against Morphic-mt.961 =============== Item was changed: ----- Method: PluggableTextMorph>>acceptTextInModel (in category 'menu commands') ----- acceptTextInModel "Inform the model that the receiver's textMorph's text should be accepted. Answer true if the model accepted ok, false otherwise" | textToAccept | + textToAccept := textMorph contents copy. - textToAccept := textMorph asText. ^setTextSelector isNil or: [setTextSelector numArgs = 2 ifTrue: [model perform: setTextSelector with: textToAccept with: self] ifFalse: [model perform: setTextSelector with: textToAccept]] ! From karlramberg at gmail.com Sun May 3 09:26:34 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sun May 3 09:26:36 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: <1430635707869-4823904.post@n4.nabble.com> References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> Message-ID: It's also hard for a user to find all preferences if every tiny widget have one. Karl On Sun, May 3, 2015 at 8:48 AM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > ...but if we want to let Morphs access those preferences, we probably still > need such a class-side abstraction in Morphs. Otherwise Morphic would be > dependent on Tools, which should not be. > > Such preference access happens in Morphs in many places right now. Even > outside initialization code, which is not good because a single morph > cannot > behave differently to the system's preferences easily. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823904.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150503/0636091e/attachment.htm From commits at source.squeak.org Sun May 3 09:30:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 09:30:13 2015 Subject: [squeak-dev] The Trunk: ST80-mt.184.mcz Message-ID: Marcel Taeumel uploaded a new version of ST80 to project The Trunk: http://source.squeak.org/trunk/ST80-mt.184.mcz ==================== Summary ==================== Name: ST80-mt.184 Author: mt Time: 3 May 2015, 11:29:52.063 am UUID: 435ddd17-290f-9447-a3fd-bbf5b6d7af81 Ancestors: ST80-mt.183 Added some missing stuff due to changes in Morphic land. =============== Diff against ST80-mt.183 =============== Item was changed: ----- Method: PluggableTextController>>accept (in category 'as yet unclassified') ----- accept view hasUnacceptedEdits ifFalse: [^ view flash]. view hasEditingConflicts ifTrue: [(self confirm: 'Caution!! This method may have been changed elsewhere since you started editing it here. Accept anyway?' translated) ifFalse: [^ self flash]]. + (view setText: paragraph text from: self) == true ifTrue: - (view setText: paragraph text from: self) ifTrue: [initialText := paragraph text copy. view ifNotNil: [view hasUnacceptedEdits: false]] . ! Item was changed: ----- Method: PluggableTextView>>update: (in category 'updating') ----- update: aSymbol "Refer to the comment in View|update:. Do nothing if the given symbol does not match any action. " aSymbol == #wantToChange ifTrue: [self canDiscardEdits ifFalse: [self promptForCancel]. ^ self]. aSymbol == #flash ifTrue: [^ controller flash]. aSymbol == getTextSelector ifTrue: [^ self updateDisplayContents]. aSymbol == getSelectionSelector ifTrue: [^ self setSelection: self getSelection]. aSymbol == #clearUserEdits ifTrue: [^ self hasUnacceptedEdits: false]. (aSymbol == #autoSelect and: [getSelectionSelector ~~ nil]) ifTrue: [ParagraphEditor abandonChangeText. "no replacement!!" ^ controller setSearch: model autoSelectString; againOrSame: true]. aSymbol == #appendEntry ifTrue: [^ controller doOccluded: [controller appendEntry]]. aSymbol == #clearText ifTrue: [^ controller doOccluded: [controller changeText: Text new]]. aSymbol == #bs ifTrue: [^ controller doOccluded: [controller bsText]]. aSymbol == #codeChangedElsewhere ifTrue: [^ self hasEditingConflicts: true]. aSymbol == #saveContents ifTrue: [^self controller saveContentsInFile]. aSymbol == #close ifTrue: + [^self topView controller closeAndUnscheduleNoTerminate]. + aSymbol == #acceptChanges ifTrue: + [^ self controller accept]. + aSymbol == #revertChanges ifTrue: + [^ self controller cancel].! - [^self topView controller closeAndUnscheduleNoTerminate] - - ! Item was added: + ----- Method: View>>balloonText: (in category 'morphic compatibility') ----- + balloonText: aString + "Unfortunately we just ignore this help text because we are not morphic" + ! Item was changed: ----- Method: View>>setBalloonText: (in category 'morphic compatibility') ----- setBalloonText: aString - "Unfortunately we just ignore this help text because we are not morphic" self flag: #deprecated. "mt: Use #balloonText: or just remove."! From commits at source.squeak.org Sun May 3 10:07:01 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 10:07:02 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.963.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.963.mcz ==================== Summary ==================== Name: Morphic-mt.963 Author: mt Time: 3 May 2015, 12:06:00.724 pm UUID: 094b8452-a15c-6c44-9078-fb9c3b23a44f Ancestors: Morphic-mt.962 Removed hard-coded extent of 16@16 for non-shrinkwrapped buttons when calculating the minimum extent. =============== Diff against Morphic-mt.962 =============== Item was changed: ----- Method: PluggableButtonMorph>>updateMinimumExtent (in category 'layout') ----- updateMinimumExtent | hMin vMin | self label isMorph ifTrue: [^ self minimumExtent: self label minExtent]. + hMin := vMin := 0. - hMin := vMin := 16. self hResizing == #shrinkWrap ifTrue: [hMin := (self font widthOfString: self label) max: self labelShrinkThreshold]. self vResizing == #shrinkWrap ifTrue: [vMin := self font height]. hMin := hMin + (2* self borderStyle width). vMin := vMin + (2* self borderStyle width). self layoutInset isRectangle ifTrue: [ hMin := hMin + self layoutInset left + self layoutInset right. vMin := vMin + self layoutInset top + self layoutInset bottom] ifFalse: [self layoutInset isPoint ifTrue: [ hMin := hMin + (2* self layoutInset x). vMin := vMin + (2* self layoutInset y)] ifFalse: [ hMin := hMin + (2* self layoutInset). vMin := vMin + (2* self layoutInset)]]. self minimumExtent: hMin @ vMin. "Since we have no submorphs, we have to resize here if we want to shrink wrap." self hResizing == #shrinkWrap ifTrue: [self width: hMin]. self vResizing == #shrinkWrap ifTrue: [self height: vMin].! From commits at source.squeak.org Sun May 3 10:08:52 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 10:08:53 2015 Subject: [squeak-dev] The Trunk: Tools-mt.617.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.617.mcz ==================== Summary ==================== Name: Tools-mt.617 Author: mt Time: 3 May 2015, 12:08:33.481 pm UUID: 550a7de0-db51-154d-873a-d2569c50c8a6 Ancestors: Tools-mt.616 "Message Names" tool refactored. =============== Diff against Tools-mt.616 =============== Item was changed: MessageSet subclass: #MessageNames + instanceVariableNames: 'searchString selectorList selectorListIndex' - instanceVariableNames: 'searchString selectorList selectorListIndex searchPane' classVariableNames: '' poolDictionaries: '' category: 'Tools-Browser'! Item was changed: ----- Method: MessageNames>>buildSearchPaneWith: (in category 'toolbuilder') ----- buildSearchPaneWith: builder + + | panelSpec textSpec buttonSpec | + panelSpec := builder pluggablePanelSpec new + layout: #horizontal; + children: OrderedCollection new; + yourself. + - | textSpec | textSpec := builder pluggableInputFieldSpec new. textSpec + model: searchString; + help: 'Type here, then hit Search.' translated; + getText: #contents; + setText: #contents:. + panelSpec children add: textSpec. + + buttonSpec := builder pluggableActionButtonSpec new. + buttonSpec model: self; + label: 'Search'; + action: #doSearch; + horizontalResizing: #shrinkWrap. + panelSpec children add: buttonSpec. + + ^ panelSpec! - name: #search; - getText: #searchString; - setText: #searchString:notifying:. - ^textSpec! Item was changed: ----- Method: MessageNames>>buildWith: (in category 'toolbuilder') ----- buildWith: builder "ToolBuilder open: MessageNames new" + + | windowSpec max searchHeight | - | windowSpec max buttonSpec result | max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5]. + searchHeight := Preferences standardDefaultTextFont height * 2. + windowSpec := self buildWindowWith: builder specs: { + (self topConstantHeightFrame: searchHeight fromLeft: 0 width: 0.5) -> [self buildSearchPaneWith: builder]. + (self frameOffsetFromTop: searchHeight fromLeft: 0 width: 0.5 bottomFraction: max) -> [self buildSelectorListWith: builder]. - (0.15@0 corner: 0.5@0.08) -> [self buildSearchPaneWith: builder]. - (0@0.08 corner: 0.5@max) -> [self buildSelectorListWith: builder]. (0.5@0.0 corner: 1.0@max) -> [self buildMessageListWith: builder]. (0@max corner: 1@1) -> [self buildCodePaneWith: builder]. }. + ^ builder build: windowSpec! - buttonSpec := builder pluggableActionButtonSpec new. - buttonSpec - model: self; - label: 'Search'; - action: [self doSearchFrom: searchPane]; - frame: (0.0@0 corner: 0.15@0.08). - windowSpec children add: buttonSpec. - - result := builder build: windowSpec. - searchPane := builder widgetAt: #search. - ^result! Item was added: + ----- Method: MessageNames>>computeMessageList (in category 'search') ----- + computeMessageList + + ^ selectorListIndex = 0 + ifTrue: [#()] + ifFalse: [self systemNavigation + allImplementorsOf: (selectorList at: selectorListIndex)]! Item was added: + ----- Method: MessageNames>>computeSelectorListFrom: (in category 'search') ----- + computeSelectorListFrom: searchString + "Compute selector list from search string. The searchString is a list of expressions separated by ;. Each expression is matched individually. An expression can be a simple string (same as *expression*), a string with double quotes (exact match) or a match expression (see String >> #match:)." + + ^ (Array streamContents: [ :stream | + (searchString findBetweenSubStrs: ';') do: [ :selPat | + (selPat first = $" and: [ selPat last = $" and: [ selPat size > 2 ] ]) + ifTrue: [ + Symbol + hasInterned: (selPat copyFrom: 2 to: selPat size - 1) + ifTrue: [ :sym | stream nextPut: sym ] ] + ifFalse: [ + | raw n m | + n := selPat occurrencesOf: $*. + m := selPat occurrencesOf: $#. + raw := ((n > 0 or: [ m > 0 ]) and: [ selPat size > (n + m) ]) + ifTrue: [ Symbol selectorsMatching: selPat ] + ifFalse: [ Symbol selectorsContaining: selPat ]. + stream nextPutAll: raw ] ] ]) + sort: [ :x :y | x caseInsensitiveLessOrEqual: y ]! Item was removed: - ----- Method: MessageNames>>computeSelectorListFromSearchString (in category 'search') ----- - computeSelectorListFromSearchString - "Compute selector list from search string. The searchString is a list of expressions separated by ;. Each expression is matched individually. An expression can be a simple string (same as *expression*), a string with double quotes (exact match) or a match expression (see String >> #match:)." - - searchString := searchString asString copyWithout: $ . "?dubious?" - ^selectorList := Cursor wait showWhile: [ - (Array streamContents: [ :stream | - (searchString findBetweenSubStrs: ';') do: [ :selPat | - (selPat first = $" and: [ selPat last = $" and: [ selPat size > 2 ] ]) - ifTrue: [ - Symbol - hasInterned: (selPat copyFrom: 2 to: selPat size - 1) - ifTrue: [ :sym | stream nextPut: sym ] ] - ifFalse: [ - | raw n m | - n := selPat occurrencesOf: $*. - m := selPat occurrencesOf: $#. - raw := ((n > 0 or: [ m > 0 ]) and: [ selPat size > (n + m) ]) - ifTrue: [ Symbol selectorsMatching: selPat ] - ifFalse: [ Symbol selectorsContaining: selPat ]. - stream nextPutAll: raw ] ] ]) - sort: [ :x :y | x caseInsensitiveLessOrEqual: y ] ]! Item was removed: - ----- Method: MessageNames>>defaultBrowserTitle (in category 'initialization') ----- - defaultBrowserTitle - ^ 'Message Names'! Item was added: + ----- Method: MessageNames>>doSearch (in category 'search') ----- + doSearch + "The user hit the Search button -- treat it as a synonym for the user having hit the Return or Enter (or cmd-s) in the type-in pane" + + searchString changed: #acceptChanges.! Item was added: + ----- Method: MessageNames>>doSearch: (in category 'search') ----- + doSearch: aSearchString + + | normalizedSearchString | + normalizedSearchString := aSearchString asString copyWithout: Character space. + + Cursor wait showWhile: [ + self selectorList: (self computeSelectorListFrom: normalizedSearchString)]. + + ^ true! Item was removed: - ----- Method: MessageNames>>doSearchFrom: (in category 'search') ----- - doSearchFrom: aPane - "The user hit the Search button -- treat it as a synonym for the user having hit the Return or Enter (or cmd-s) in the type-in pane" - - aPane accept. - aPane selectAll! Item was added: + ----- Method: MessageNames>>frameOffsetFromTop:fromLeft:width:bottomFraction: (in category 'toolbuilder') ----- + frameOffsetFromTop: height fromLeft: leftFraction width: rightFraction bottomFraction: bottomFraction + ^LayoutFrame new + topFraction: 0 offset: height; + leftFraction: leftFraction offset: 0; + rightFraction: (leftFraction + rightFraction) offset: 0; + bottomFraction: bottomFraction offset: 0; + yourself.! Item was added: + ----- Method: MessageNames>>initialize (in category 'initialization') ----- + initialize + + super initialize. + + searchString := ValueHolder new contents: ''. + searchString addDependent: self. + + selectorList := #(). + selectorListIndex := 0.! Item was added: + ----- Method: MessageNames>>labelString (in category 'initialization') ----- + labelString + + ^ self searchString + ifEmpty: ['Message Names'] + ifNotEmpty: [:s | 'Message names containing "', s asString asLowercase, '"']! Item was removed: - ----- Method: MessageNames>>messageList (in category 'selector list') ----- - messageList - "Answer the receiver's message list, computing it if necessary. The way - to force a recomputation is to set the messageList to nil" - messageList - ifNil: [messageList := selectorListIndex = 0 - ifTrue: [#()] - ifFalse: [self systemNavigation - allImplementorsOf: (selectorList at: selectorListIndex)]. - self - messageListIndex: (messageList size > 0 - ifTrue: [1] - ifFalse: [0])]. - ^ messageList! Item was added: + ----- Method: MessageNames>>messageList: (in category 'message list') ----- + messageList: someObjects + + messageList := someObjects. + self changed: #messageList. + + self messageListIndex: (messageList size > 0 + ifTrue: [1] + ifFalse: [0]).! Item was changed: ----- Method: MessageNames>>searchString (in category 'search') ----- searchString - "Answer the current searchString, initializing it if need be" + ^ searchString contents! - | pane | - searchString isEmptyOrNil ifTrue: - [searchString := 'type here, then hit Search'. - pane := self containingWindow findDeepSubmorphThat: - [:m | m knownName = 'Search'] ifAbsent: ["this happens during window creation" ^ searchString]. - pane setText: searchString. - pane setTextMorphToSelectAllOnMouseEnter. - pane selectAll]. - ^ searchString! Item was changed: ----- Method: MessageNames>>searchString: (in category 'search') ----- searchString: aString + + searchString contents: aString.! - "Set the current searchString" - self searchString: aString notifying: nil! Item was removed: - ----- Method: MessageNames>>searchString:notifying: (in category 'search') ----- - searchString: aString notifying: aController - "Take what the user typed and find all selectors containing it" - - searchString := aString asString copyWithout: $ . - self containingWindow ifNotNil:[:w| w setLabel: 'Message names containing "', searchString asLowercase, '"']. - selectorList := nil. - self changed: #selectorList. - self changed: #messageList. - ^ true! Item was changed: + ----- Method: MessageNames>>selectedMessageName (in category 'message list') ----- - ----- Method: MessageNames>>selectedMessageName (in category 'selection') ----- selectedMessageName selectorList basicSize = 0 ifTrue: [^ nil]. "Deals with selectorList nil or empty" ^selectorList at: (selectorListIndex max: 1) ifAbsent: [nil] "If no selection we can still find a selector"! Item was changed: ----- Method: MessageNames>>selectorList (in category 'selector list') ----- selectorList - "Answer the selectorList" - selectorList ifNil: - [self computeSelectorListFromSearchString. - selectorListIndex := selectorList size > 0 - ifTrue: [1] - ifFalse: [0]. - messageList := nil]. ^ selectorList! Item was added: + ----- Method: MessageNames>>selectorList: (in category 'selector list') ----- + selectorList: someObjects + "Answer the selectorList" + + selectorList := someObjects. + self changed: #selectorList. + + "Select first result if any." + self selectorListIndex: (selectorList size > 0 + ifTrue: [1] + ifFalse: [0]).! Item was changed: ----- Method: MessageNames>>selectorListIndex: (in category 'selector list') ----- selectorListIndex: anInteger "Set the selectorListIndex as specified, and propagate consequences" selectorListIndex := anInteger. - selectorListIndex = 0 - ifTrue: [^ self]. - messageList := nil. self changed: #selectorListIndex. + + messageList := self computeMessageList. + self changed: #messageList.! - self changed: #messageList! Item was changed: + ----- Method: MessageNames>>selectorListKey:from: (in category 'selector list') ----- - ----- Method: MessageNames>>selectorListKey:from: (in category 'initialization') ----- selectorListKey: aChar from: view "Respond to a Command key in the message-list pane." aChar == $n ifTrue: [^ self browseSenders]. aChar == $c ifTrue: [^ self copyName]. aChar == $b ifTrue: [^ self browseMethodFull]. ! Item was changed: ----- Method: MessageNames>>showOnlyImplementedSelectors (in category 'search') ----- showOnlyImplementedSelectors "Caution -- can be slow!! Filter my selector list down such that it only shows selectors that are actually implemented somewhere in the system." + self okToChange ifFalse: [^ self]. + + Cursor wait showWhile: [ + self selectorList: (self systemNavigation allSelectorsWithAnyImplementorsIn: selectorList)].! - self okToChange - ifTrue: [Cursor wait - showWhile: [selectorList := self systemNavigation allSelectorsWithAnyImplementorsIn: selectorList. - self changed: #selectorList. - self changed: #messageList]]! Item was changed: + ----- Method: MessageNames>>topConstantHeightFrame:fromLeft:width: (in category 'toolbuilder') ----- - ----- Method: MessageNames>>topConstantHeightFrame:fromLeft:width: (in category 'as yet unclassified') ----- topConstantHeightFrame: height fromLeft: leftFraction width: rightFraction ^LayoutFrame new topFraction: 0 offset: 0; leftFraction: leftFraction offset: 0; rightFraction: (leftFraction + rightFraction) offset: 0; bottomFraction: 0 offset: height; yourself.! Item was added: + ----- Method: MessageNames>>update: (in category 'updating') ----- + update: aspect + + aspect == #contents + ifTrue: [ + self changed: #labelString. + self doSearch: self searchString]. + + super update: aspect.! From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 09:56:33 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 10:11:57 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> Message-ID: <1430646993279-4823948.post@n4.nabble.com> Why? No "user" should have to scan classes. The Preferences Browser is for that. It integrates all scattered preferences. And it supports search as well as browsing the acutal senders. It's a good thing that each new package/class can bring new preferences with it. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823948.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From hannes.hirzel at gmail.com Sun May 3 10:30:01 2015 From: hannes.hirzel at gmail.com (H. Hirzel) Date: Sun May 3 10:30:03 2015 Subject: [squeak-dev] The Trunk: ST80-mt.184.mcz In-Reply-To: <5545eaa6.8149340a.55c2.ffffde40SMTPIN_ADDED_MISSING@mx.google.com> References: <5545eaa6.8149340a.55c2.ffffde40SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Thank you for working on this! Hannes Hirzel On Sun, 3 May 2015 09:29:54.509 0000, commits@source.squeak.org wrote: > Marcel Taeumel uploaded a new version of ST80 to project The Trunk: > http://source.squeak.org/trunk/ST80-mt.184.mcz > > ==================== Summary ==================== > > Name: ST80-mt.184 > Author: mt > Time: 3 May 2015, 11:29:52.063 am > UUID: 435ddd17-290f-9447-a3fd-bbf5b6d7af81 > Ancestors: ST80-mt.183 > > Added some missing stuff due to changes in Morphic land. > > =============== Diff against ST80-mt.183 =============== > > Item was changed: > ----- Method: PluggableTextController>>accept (in category 'as yet > unclassified') ----- > accept > view hasUnacceptedEdits ifFalse: [^ view flash]. > view hasEditingConflicts ifTrue: > [(self confirm: > 'Caution!! This method may have been > changed elsewhere since you started > editing it here. Accept anyway?' translated) ifFalse: [^ self flash]]. > > + (view setText: paragraph text from: self) == true ifTrue: > - (view setText: paragraph text from: self) ifTrue: > [initialText := paragraph text copy. > view ifNotNil: [view hasUnacceptedEdits: false]] . > ! > > Item was changed: > ----- Method: PluggableTextView>>update: (in category 'updating') ----- > update: aSymbol > "Refer to the comment in View|update:. Do nothing if the given symbol > does not match any action. " > > aSymbol == #wantToChange ifTrue: > [self canDiscardEdits ifFalse: [self promptForCancel]. ^ self]. > aSymbol == #flash ifTrue: [^ controller flash]. > aSymbol == getTextSelector ifTrue: [^ self updateDisplayContents]. > aSymbol == getSelectionSelector ifTrue: [^ self setSelection: self > getSelection]. > aSymbol == #clearUserEdits ifTrue: [^ self hasUnacceptedEdits: false]. > (aSymbol == #autoSelect and: [getSelectionSelector ~~ nil]) ifTrue: > [ParagraphEditor abandonChangeText. "no replacement!!" > ^ controller setSearch: model autoSelectString; > againOrSame: true]. > aSymbol == #appendEntry ifTrue: > [^ controller doOccluded: [controller appendEntry]]. > aSymbol == #clearText ifTrue: > [^ controller doOccluded: > [controller changeText: Text new]]. > aSymbol == #bs ifTrue: > [^ controller doOccluded: > [controller bsText]]. > aSymbol == #codeChangedElsewhere ifTrue: > [^ self hasEditingConflicts: true]. > aSymbol == #saveContents ifTrue: > [^self controller saveContentsInFile]. > aSymbol == #close ifTrue: > + [^self topView controller closeAndUnscheduleNoTerminate]. > + aSymbol == #acceptChanges ifTrue: > + [^ self controller accept]. > + aSymbol == #revertChanges ifTrue: > + [^ self controller cancel].! > - [^self topView controller closeAndUnscheduleNoTerminate] > - > - ! > > Item was added: > + ----- Method: View>>balloonText: (in category 'morphic compatibility') > ----- > + balloonText: aString > + "Unfortunately we just ignore this help text because we are not morphic" > + ! > > Item was changed: > ----- Method: View>>setBalloonText: (in category 'morphic compatibility') > ----- > setBalloonText: aString > - "Unfortunately we just ignore this help text because we are not morphic" > > self flag: #deprecated. "mt: Use #balloonText: or just remove."! > > > From hannes.hirzel at gmail.com Sun May 3 10:54:07 2015 From: hannes.hirzel at gmail.com (H. Hirzel) Date: Sun May 3 10:54:09 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: <1430646993279-4823948.post@n4.nabble.com> References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: Very interesting discussion. Is it possible to summarize the outcome and post it at a more prominent place? In a separate thread, the wiki or in a class comment? HH On 5/3/15, Marcel Taeumel wrote: > Why? No "user" should have to scan classes. The Preferences Browser is for > that. It integrates all scattered preferences. And it supports search as > well as browsing the acutal senders. > > It's a good thing that each new package/class can bring new preferences > with > it. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823948.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From karlramberg at gmail.com Sun May 3 11:50:07 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sun May 3 11:50:10 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: <1430646993279-4823948.post@n4.nabble.com> References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: I mean this more like: when we have separate preferences for every widget it will be hard,confusing and tedious to hunt down every setting for color and corner rounding etc. to change the look of the system. Even if the PreferenceBrowser access them all, it will become overwhelming with several hundred preferences On Sun, May 3, 2015 at 11:56 AM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Why? No "user" should have to scan classes. The Preferences Browser is for > that. It integrates all scattered preferences. And it supports search as > well as browsing the acutal senders. > > It's a good thing that each new package/class can bring new preferences > with > it. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823948.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150503/f26a114e/attachment.htm From leves at elte.hu Sun May 3 12:12:28 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sun May 3 12:12:32 2015 Subject: [squeak-dev] The Trunk: Collections-tfel.623.mcz In-Reply-To: References: Message-ID: On Fri, 1 May 2015, commits@source.squeak.org wrote: > Tim Felgentreff uploaded a new version of Collections to project The Trunk: > http://source.squeak.org/trunk/Collections-tfel.623.mcz > > ==================== Summary ==================== > > Name: Collections-tfel.623 > Author: tfel > Time: 1 May 2015, 11:06:35.625 am > UUID: baf2902d-52b9-2442-a513-8a5a6ff0ce30 > Ancestors: Collections-nice.622 > > fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 If I'm not mistaken, this is the slang code that gets compiled to C. Does slang support #max:? Levente > > =============== Diff against Collections-nice.622 =============== > > Item was changed: > ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- > findSubstring: key in: body startingAt: start matchTable: matchTable > "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. > > The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." > | index | > > > > > > key size = 0 ifTrue: [^ 0]. > + (start max: 1) to: body size - key size + 1 do: > - start to: body size - key size + 1 do: > [:startIndex | > index := 1. > [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) > = (matchTable at: (key at: index) asciiValue + 1)] > whileTrue: > [index = key size ifTrue: [^ startIndex]. > index := index+1]]. > ^ 0 > " > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 > ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 > ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 > ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 > "! > > > From commits at source.squeak.org Sun May 3 12:34:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 12:34:28 2015 Subject: [squeak-dev] The Trunk: Collections-ul.627.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.627.mcz ==================== Summary ==================== Name: Collections-ul.627 Author: ul Time: 3 May 2015, 2:23:44.317 pm UUID: 6562bd09-b06e-436f-8771-a7cf2ecf6a25 Ancestors: Collections-mt.626, Collections-ul.624 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. =============== Diff against Collections-mt.626 =============== Item was changed: Magnitude subclass: #Character instanceVariableNames: 'value' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + value < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | numArgs aStream offs |. - (numArgs := self numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sun May 3 12:42:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 12:42:14 2015 Subject: [squeak-dev] The Trunk: Collections-ul.628.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.628.mcz ==================== Summary ==================== Name: Collections-ul.628 Author: ul Time: 3 May 2015, 2:37:08.318 pm UUID: 45ec1e72-ea02-42fc-8dcb-10a1dfd22209 Ancestors: Collections-ul.627, Collections-ul.625 Merged Collections-ul.625. =============== Diff against Collections-ul.627 =============== Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + value > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: value)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + value > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: value)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! From commits at source.squeak.org Sun May 3 12:42:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 12:42:35 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.964.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.964.mcz ==================== Summary ==================== Name: Morphic-mt.964 Author: mt Time: 3 May 2015, 2:41:32.279 pm UUID: 99fbd4f1-a84a-b344-90f2-9f28f14f5e4a Ancestors: Morphic-mt.963 Moved specialized list morph for message categories into deprecation. All browsers have regular lists morphs--even for message category lists. =============== Diff against Morphic-mt.963 =============== Item was removed: - PluggableListMorph subclass: #PluggableMessageCategoryListMorph - instanceVariableNames: 'getRawListSelector priorRawList' - classVariableNames: '' - poolDictionaries: '' - category: 'Morphic-Pluggable Widgets'! - - !PluggableMessageCategoryListMorph commentStamp: '' prior: 0! - A variant of PluggableListMorph designed specially for efficient handling of the --all-- feature in message-list panes. In order to be able *quickly* to check whether there has been an external change to the list, we cache the raw list for identity comparison (the actual list is a combination of the --all-- element and the the actual list).! Item was removed: - ----- Method: PluggableMessageCategoryListMorph class>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- - on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel - ^ self new on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel! Item was removed: - ----- Method: PluggableMessageCategoryListMorph>>getList (in category 'model access') ----- - getList - "Differs from the generic in that here we obtain and cache the raw list, then cons it together with the special '-- all --' item to produce the list to be used in the browser. This special handling is done in order to avoid excessive and unnecessary reformulation of the list in the step method" - - getRawListSelector == nil ifTrue: ["should not happen!!" priorRawList := nil. ^ #()]. - model classListIndex = 0 ifTrue: [^ priorRawList := list := Array new]. - priorRawList := model perform: getRawListSelector. - list := (Array with: ClassOrganizer allCategory), priorRawList. - ^list! Item was removed: - ----- Method: PluggableMessageCategoryListMorph>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- - on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel - self model: anObject. - getListSelector := getListSel. - getIndexSelector := getSelectionSel. - setIndexSelector := setSelectionSel. - getMenuSelector := getMenuSel. - keystrokeActionSelector := keyActionSel. - autoDeselect := true. - self borderWidth: 1. - getRawListSelector := getRawSel. - self updateList. - self selectionIndex: self getCurrentSelectionIndex. - self initForKeystrokes! Item was removed: - ----- Method: PluggableMessageCategoryListMorph>>verifyContents (in category 'updating') ----- - verifyContents - | newList existingSelection anIndex newRawList | - (model editSelection == #editComment) ifTrue: [^ self]. - model classListIndex = 0 ifTrue: [^ self]. - newRawList := model perform: getRawListSelector. - newRawList == priorRawList ifTrue: [^ self]. "The usual case; very fast" - priorRawList := newRawList. - newList := (Array with: ClassOrganizer allCategory), priorRawList. - list = newList ifTrue: [^ self]. - existingSelection := self selection. - self updateList. - (anIndex := newList indexOf: existingSelection ifAbsent: [nil]) - ifNotNil: - [model noteSelectionIndex: anIndex for: getListSelector. - self selectionIndex: anIndex] - ifNil: - [self changeModelSelection: 0]! From commits at source.squeak.org Sun May 3 12:43:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 12:43:21 2015 Subject: [squeak-dev] The Trunk: 46Deprecated-mt.2.mcz Message-ID: Marcel Taeumel uploaded a new version of 46Deprecated to project The Trunk: http://source.squeak.org/trunk/46Deprecated-mt.2.mcz ==================== Summary ==================== Name: 46Deprecated-mt.2 Author: mt Time: 3 May 2015, 2:43:14.241 pm UUID: a45140cf-2faa-8642-a1b8-2f81eaea8990 Ancestors: 46Deprecated-mt.1 Added a widget that was once used for showing message category lists. =============== Diff against 46Deprecated-mt.1 =============== Item was added: + SystemOrganization addCategory: #'46Deprecated-Morphic-Pluggable Widgets'! Item was added: + PluggableListMorph subclass: #PluggableMessageCategoryListMorph + instanceVariableNames: 'getRawListSelector priorRawList' + classVariableNames: '' + poolDictionaries: '' + category: '46Deprecated-Morphic-Pluggable Widgets'! + + !PluggableMessageCategoryListMorph commentStamp: '' prior: 0! + A variant of PluggableListMorph designed specially for efficient handling of the --all-- feature in message-list panes. In order to be able *quickly* to check whether there has been an external change to the list, we cache the raw list for identity comparison (the actual list is a combination of the --all-- element and the the actual list).! Item was added: + ----- Method: PluggableMessageCategoryListMorph class>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- + on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel + ^ self new on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel! Item was added: + ----- Method: PluggableMessageCategoryListMorph>>getList (in category 'model access') ----- + getList + "Differs from the generic in that here we obtain and cache the raw list, then cons it together with the special '-- all --' item to produce the list to be used in the browser. This special handling is done in order to avoid excessive and unnecessary reformulation of the list in the step method" + + getRawListSelector == nil ifTrue: ["should not happen!!" priorRawList := nil. ^ #()]. + model classListIndex = 0 ifTrue: [^ priorRawList := list := Array new]. + priorRawList := model perform: getRawListSelector. + list := (Array with: ClassOrganizer allCategory), priorRawList. + ^list! Item was added: + ----- Method: PluggableMessageCategoryListMorph>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- + on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel + self model: anObject. + getListSelector := getListSel. + getIndexSelector := getSelectionSel. + setIndexSelector := setSelectionSel. + getMenuSelector := getMenuSel. + keystrokeActionSelector := keyActionSel. + autoDeselect := true. + self borderWidth: 1. + getRawListSelector := getRawSel. + self updateList. + self selectionIndex: self getCurrentSelectionIndex. + self initForKeystrokes! Item was added: + ----- Method: PluggableMessageCategoryListMorph>>verifyContents (in category 'updating') ----- + verifyContents + | newList existingSelection anIndex newRawList | + (model editSelection == #editComment) ifTrue: [^ self]. + model classListIndex = 0 ifTrue: [^ self]. + newRawList := model perform: getRawListSelector. + newRawList == priorRawList ifTrue: [^ self]. "The usual case; very fast" + priorRawList := newRawList. + newList := (Array with: ClassOrganizer allCategory), priorRawList. + list = newList ifTrue: [^ self]. + existingSelection := self selection. + self updateList. + (anIndex := newList indexOf: existingSelection ifAbsent: [nil]) + ifNotNil: + [model noteSelectionIndex: anIndex for: getListSelector. + self selectionIndex: anIndex] + ifNil: + [self changeModelSelection: 0]! From leves at elte.hu Sun May 3 12:44:59 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sun May 3 12:45:03 2015 Subject: [squeak-dev] The Trunk: Tools-mt.617.mcz In-Reply-To: References: Message-ID: This makes MorphicUIManagerTest >> #testShowAllBinParts fail, because the searchString ValueHolder holds nil instead of a string. I suspect that the reason for this is: MorphicUIManagerTest class >> #prototypicalToolWindow "Answer an example of myself seen in a tool window, for the benefit of parts-launching tools" ^ self methodBrowserSearchingFor: nil Levente On Sun, 3 May 2015, commits@source.squeak.org wrote: > Marcel Taeumel uploaded a new version of Tools to project The Trunk: > http://source.squeak.org/trunk/Tools-mt.617.mcz > > ==================== Summary ==================== > > Name: Tools-mt.617 > Author: mt > Time: 3 May 2015, 12:08:33.481 pm > UUID: 550a7de0-db51-154d-873a-d2569c50c8a6 > Ancestors: Tools-mt.616 > > "Message Names" tool refactored. > > =============== Diff against Tools-mt.616 =============== > > Item was changed: > MessageSet subclass: #MessageNames > + instanceVariableNames: 'searchString selectorList selectorListIndex' > - instanceVariableNames: 'searchString selectorList selectorListIndex searchPane' > classVariableNames: '' > poolDictionaries: '' > category: 'Tools-Browser'! > > Item was changed: > ----- Method: MessageNames>>buildSearchPaneWith: (in category 'toolbuilder') ----- > buildSearchPaneWith: builder > + > + | panelSpec textSpec buttonSpec | > + panelSpec := builder pluggablePanelSpec new > + layout: #horizontal; > + children: OrderedCollection new; > + yourself. > + > - | textSpec | > textSpec := builder pluggableInputFieldSpec new. > textSpec > + model: searchString; > + help: 'Type here, then hit Search.' translated; > + getText: #contents; > + setText: #contents:. > + panelSpec children add: textSpec. > + > + buttonSpec := builder pluggableActionButtonSpec new. > + buttonSpec > model: self; > + label: 'Search'; > + action: #doSearch; > + horizontalResizing: #shrinkWrap. > + panelSpec children add: buttonSpec. > + > + ^ panelSpec! > - name: #search; > - getText: #searchString; > - setText: #searchString:notifying:. > - ^textSpec! > > Item was changed: > ----- Method: MessageNames>>buildWith: (in category 'toolbuilder') ----- > buildWith: builder > "ToolBuilder open: MessageNames new" > + > + | windowSpec max searchHeight | > - | windowSpec max buttonSpec result | > max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5]. > + searchHeight := Preferences standardDefaultTextFont height * 2. > + > windowSpec := self buildWindowWith: builder specs: { > + (self topConstantHeightFrame: searchHeight fromLeft: 0 width: 0.5) -> [self buildSearchPaneWith: builder]. > + (self frameOffsetFromTop: searchHeight fromLeft: 0 width: 0.5 bottomFraction: max) -> [self buildSelectorListWith: builder]. > - (0.15@0 corner: 0.5@0.08) -> [self buildSearchPaneWith: builder]. > - (0@0.08 corner: 0.5@max) -> [self buildSelectorListWith: builder]. > (0.5@0.0 corner: 1.0@max) -> [self buildMessageListWith: builder]. > (0@max corner: 1@1) -> [self buildCodePaneWith: builder]. > }. > > + ^ builder build: windowSpec! > - buttonSpec := builder pluggableActionButtonSpec new. > - buttonSpec > - model: self; > - label: 'Search'; > - action: [self doSearchFrom: searchPane]; > - frame: (0.0@0 corner: 0.15@0.08). > - windowSpec children add: buttonSpec. > - > - result := builder build: windowSpec. > - searchPane := builder widgetAt: #search. > - ^result! > > Item was added: > + ----- Method: MessageNames>>computeMessageList (in category 'search') ----- > + computeMessageList > + > + ^ selectorListIndex = 0 > + ifTrue: [#()] > + ifFalse: [self systemNavigation > + allImplementorsOf: (selectorList at: selectorListIndex)]! > > Item was added: > + ----- Method: MessageNames>>computeSelectorListFrom: (in category 'search') ----- > + computeSelectorListFrom: searchString > + "Compute selector list from search string. The searchString is a list of expressions separated by ;. Each expression is matched individually. An expression can be a simple string (same as *expression*), a string with double quotes (exact match) or a match expression (see String >> #match:)." > + > + ^ (Array streamContents: [ :stream | > + (searchString findBetweenSubStrs: ';') do: [ :selPat | > + (selPat first = $" and: [ selPat last = $" and: [ selPat size > 2 ] ]) > + ifTrue: [ > + Symbol > + hasInterned: (selPat copyFrom: 2 to: selPat size - 1) > + ifTrue: [ :sym | stream nextPut: sym ] ] > + ifFalse: [ > + | raw n m | > + n := selPat occurrencesOf: $*. > + m := selPat occurrencesOf: $#. > + raw := ((n > 0 or: [ m > 0 ]) and: [ selPat size > (n + m) ]) > + ifTrue: [ Symbol selectorsMatching: selPat ] > + ifFalse: [ Symbol selectorsContaining: selPat ]. > + stream nextPutAll: raw ] ] ]) > + sort: [ :x :y | x caseInsensitiveLessOrEqual: y ]! > > Item was removed: > - ----- Method: MessageNames>>computeSelectorListFromSearchString (in category 'search') ----- > - computeSelectorListFromSearchString > - "Compute selector list from search string. The searchString is a list of expressions separated by ;. Each expression is matched individually. An expression can be a simple string (same as *expression*), a string with double quotes (exact match) or a match expression (see String >> #match:)." > - > - searchString := searchString asString copyWithout: $ . "?dubious?" > - ^selectorList := Cursor wait showWhile: [ > - (Array streamContents: [ :stream | > - (searchString findBetweenSubStrs: ';') do: [ :selPat | > - (selPat first = $" and: [ selPat last = $" and: [ selPat size > 2 ] ]) > - ifTrue: [ > - Symbol > - hasInterned: (selPat copyFrom: 2 to: selPat size - 1) > - ifTrue: [ :sym | stream nextPut: sym ] ] > - ifFalse: [ > - | raw n m | > - n := selPat occurrencesOf: $*. > - m := selPat occurrencesOf: $#. > - raw := ((n > 0 or: [ m > 0 ]) and: [ selPat size > (n + m) ]) > - ifTrue: [ Symbol selectorsMatching: selPat ] > - ifFalse: [ Symbol selectorsContaining: selPat ]. > - stream nextPutAll: raw ] ] ]) > - sort: [ :x :y | x caseInsensitiveLessOrEqual: y ] ]! > > Item was removed: > - ----- Method: MessageNames>>defaultBrowserTitle (in category 'initialization') ----- > - defaultBrowserTitle > - ^ 'Message Names'! > > Item was added: > + ----- Method: MessageNames>>doSearch (in category 'search') ----- > + doSearch > + "The user hit the Search button -- treat it as a synonym for the user having hit the Return or Enter (or cmd-s) in the type-in pane" > + > + searchString changed: #acceptChanges.! > > Item was added: > + ----- Method: MessageNames>>doSearch: (in category 'search') ----- > + doSearch: aSearchString > + > + | normalizedSearchString | > + normalizedSearchString := aSearchString asString copyWithout: Character space. > + > + Cursor wait showWhile: [ > + self selectorList: (self computeSelectorListFrom: normalizedSearchString)]. > + > + ^ true! > > Item was removed: > - ----- Method: MessageNames>>doSearchFrom: (in category 'search') ----- > - doSearchFrom: aPane > - "The user hit the Search button -- treat it as a synonym for the user having hit the Return or Enter (or cmd-s) in the type-in pane" > - > - aPane accept. > - aPane selectAll! > > Item was added: > + ----- Method: MessageNames>>frameOffsetFromTop:fromLeft:width:bottomFraction: (in category 'toolbuilder') ----- > + frameOffsetFromTop: height fromLeft: leftFraction width: rightFraction bottomFraction: bottomFraction > + ^LayoutFrame new > + topFraction: 0 offset: height; > + leftFraction: leftFraction offset: 0; > + rightFraction: (leftFraction + rightFraction) offset: 0; > + bottomFraction: bottomFraction offset: 0; > + yourself.! > > Item was added: > + ----- Method: MessageNames>>initialize (in category 'initialization') ----- > + initialize > + > + super initialize. > + > + searchString := ValueHolder new contents: ''. > + searchString addDependent: self. > + > + selectorList := #(). > + selectorListIndex := 0.! > > Item was added: > + ----- Method: MessageNames>>labelString (in category 'initialization') ----- > + labelString > + > + ^ self searchString > + ifEmpty: ['Message Names'] > + ifNotEmpty: [:s | 'Message names containing "', s asString asLowercase, '"']! > > Item was removed: > - ----- Method: MessageNames>>messageList (in category 'selector list') ----- > - messageList > - "Answer the receiver's message list, computing it if necessary. The way > - to force a recomputation is to set the messageList to nil" > - messageList > - ifNil: [messageList := selectorListIndex = 0 > - ifTrue: [#()] > - ifFalse: [self systemNavigation > - allImplementorsOf: (selectorList at: selectorListIndex)]. > - self > - messageListIndex: (messageList size > 0 > - ifTrue: [1] > - ifFalse: [0])]. > - ^ messageList! > > Item was added: > + ----- Method: MessageNames>>messageList: (in category 'message list') ----- > + messageList: someObjects > + > + messageList := someObjects. > + self changed: #messageList. > + > + self messageListIndex: (messageList size > 0 > + ifTrue: [1] > + ifFalse: [0]).! > > Item was changed: > ----- Method: MessageNames>>searchString (in category 'search') ----- > searchString > - "Answer the current searchString, initializing it if need be" > > + ^ searchString contents! > - | pane | > - searchString isEmptyOrNil ifTrue: > - [searchString := 'type here, then hit Search'. > - pane := self containingWindow findDeepSubmorphThat: > - [:m | m knownName = 'Search'] ifAbsent: ["this happens during window creation" ^ searchString]. > - pane setText: searchString. > - pane setTextMorphToSelectAllOnMouseEnter. > - pane selectAll]. > - ^ searchString! > > Item was changed: > ----- Method: MessageNames>>searchString: (in category 'search') ----- > searchString: aString > + > + searchString contents: aString.! > - "Set the current searchString" > - self searchString: aString notifying: nil! > > Item was removed: > - ----- Method: MessageNames>>searchString:notifying: (in category 'search') ----- > - searchString: aString notifying: aController > - "Take what the user typed and find all selectors containing it" > - > - searchString := aString asString copyWithout: $ . > - self containingWindow ifNotNil:[:w| w setLabel: 'Message names containing "', searchString asLowercase, '"']. > - selectorList := nil. > - self changed: #selectorList. > - self changed: #messageList. > - ^ true! > > Item was changed: > + ----- Method: MessageNames>>selectedMessageName (in category 'message list') ----- > - ----- Method: MessageNames>>selectedMessageName (in category 'selection') ----- > selectedMessageName > selectorList basicSize = 0 ifTrue: [^ nil]. "Deals with selectorList nil or empty" > ^selectorList at: (selectorListIndex max: 1) ifAbsent: [nil] "If no selection we can still find a selector"! > > Item was changed: > ----- Method: MessageNames>>selectorList (in category 'selector list') ----- > selectorList > - "Answer the selectorList" > > - selectorList ifNil: > - [self computeSelectorListFromSearchString. > - selectorListIndex := selectorList size > 0 > - ifTrue: [1] > - ifFalse: [0]. > - messageList := nil]. > ^ selectorList! > > Item was added: > + ----- Method: MessageNames>>selectorList: (in category 'selector list') ----- > + selectorList: someObjects > + "Answer the selectorList" > + > + selectorList := someObjects. > + self changed: #selectorList. > + > + "Select first result if any." > + self selectorListIndex: (selectorList size > 0 > + ifTrue: [1] > + ifFalse: [0]).! > > Item was changed: > ----- Method: MessageNames>>selectorListIndex: (in category 'selector list') ----- > selectorListIndex: anInteger > "Set the selectorListIndex as specified, and propagate consequences" > > selectorListIndex := anInteger. > - selectorListIndex = 0 > - ifTrue: [^ self]. > - messageList := nil. > self changed: #selectorListIndex. > + > + messageList := self computeMessageList. > + self changed: #messageList.! > - self changed: #messageList! > > Item was changed: > + ----- Method: MessageNames>>selectorListKey:from: (in category 'selector list') ----- > - ----- Method: MessageNames>>selectorListKey:from: (in category 'initialization') ----- > selectorListKey: aChar from: view > "Respond to a Command key in the message-list pane." > > aChar == $n ifTrue: [^ self browseSenders]. > aChar == $c ifTrue: [^ self copyName]. > aChar == $b ifTrue: [^ self browseMethodFull]. > ! > > Item was changed: > ----- Method: MessageNames>>showOnlyImplementedSelectors (in category 'search') ----- > showOnlyImplementedSelectors > "Caution -- can be slow!! Filter my selector list down such that it only > shows selectors that are actually implemented somewhere in the system." > + self okToChange ifFalse: [^ self]. > + > + Cursor wait showWhile: [ > + self selectorList: (self systemNavigation allSelectorsWithAnyImplementorsIn: selectorList)].! > - self okToChange > - ifTrue: [Cursor wait > - showWhile: [selectorList := self systemNavigation allSelectorsWithAnyImplementorsIn: selectorList. > - self changed: #selectorList. > - self changed: #messageList]]! > > Item was changed: > + ----- Method: MessageNames>>topConstantHeightFrame:fromLeft:width: (in category 'toolbuilder') ----- > - ----- Method: MessageNames>>topConstantHeightFrame:fromLeft:width: (in category 'as yet unclassified') ----- > topConstantHeightFrame: height fromLeft: leftFraction width: rightFraction > ^LayoutFrame new > topFraction: 0 offset: 0; > leftFraction: leftFraction offset: 0; > rightFraction: (leftFraction + rightFraction) offset: 0; > bottomFraction: 0 offset: height; > yourself.! > > Item was added: > + ----- Method: MessageNames>>update: (in category 'updating') ----- > + update: aspect > + > + aspect == #contents > + ifTrue: [ > + self changed: #labelString. > + self doSearch: self searchString]. > + > + super update: aspect.! > > > From commits at source.squeak.org Sun May 3 13:13:51 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 13:13:52 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Kernel-mt.88.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Kernel to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Kernel-mt.88.mcz ==================== Summary ==================== Name: ToolBuilder-Kernel-mt.88 Author: mt Time: 3 May 2015, 3:13:44.5 pm UUID: 884665b2-d8a4-ba45-baf2-96fe602e2efb Ancestors: ToolBuilder-Kernel-mt.87 Added support for spacers in tool builder. =============== Diff against ToolBuilder-Kernel-mt.87 =============== Item was added: + PluggableWidgetSpec subclass: #PluggableSpacerSpec + instanceVariableNames: 'extent' + classVariableNames: '' + poolDictionaries: '' + category: 'ToolBuilder-Kernel'! Item was added: + ----- Method: PluggableSpacerSpec>>buildWith: (in category 'building') ----- + buildWith: builder + ^builder buildPluggableSpacer: self! Item was added: + ----- Method: PluggableSpacerSpec>>color (in category 'accessing') ----- + color + + ^ super color ifNil: [Color transparent]! Item was added: + ----- Method: PluggableSpacerSpec>>extent (in category 'layout hints') ----- + extent + + ^ extent ifNil: [5@5]! Item was added: + ----- Method: PluggableSpacerSpec>>extent: (in category 'layout hints') ----- + extent: aPoint + + extent := aPoint.! Item was added: + ----- Method: PluggableSpacerSpec>>fillSpaceHorizontally (in category 'convenience') ----- + fillSpaceHorizontally + + self horizontalResizing: #spaceFill.! Item was added: + ----- Method: PluggableSpacerSpec>>fillSpaceVertically (in category 'convenience') ----- + fillSpaceVertically + + self verticalResizing: #spaceFill.! Item was added: + ----- Method: PluggableSpacerSpec>>horizontalResizing (in category 'accessing') ----- + horizontalResizing + + ^ super horizontalResizing ifNil: [#rigid]! Item was added: + ----- Method: PluggableSpacerSpec>>verticalResizing (in category 'accessing') ----- + verticalResizing + + ^ super verticalResizing ifNil: [#rigid]! Item was added: + ----- Method: ToolBuilder>>buildPluggableSpacer: (in category 'widgets required') ----- + buildPluggableSpacer: aSpec + + ^ self subclassResponsibility! Item was added: + ----- Method: ToolBuilder>>pluggableSpacerSpec (in category 'defaults') ----- + pluggableSpacerSpec + ^ PluggableSpacerSpec! From commits at source.squeak.org Sun May 3 13:14:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 13:14:46 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-MVC-mt.42.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-MVC to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-MVC-mt.42.mcz ==================== Summary ==================== Name: ToolBuilder-MVC-mt.42 Author: mt Time: 3 May 2015, 3:14:38.18 pm UUID: f1b2eb4e-2140-c445-a31f-c4c95ad44334 Ancestors: ToolBuilder-MVC-mt.41 A simple implementation for spacers. =============== Diff against ToolBuilder-MVC-mt.41 =============== Item was added: + ----- Method: MVCToolBuilder>>buildPluggableSpacer: (in category 'widgets required') ----- + buildPluggableSpacer: aSpec + + | widget | + widget := View new. + self register: widget id: aSpec name. + + widget borderWidth: 0. + widget backgroundColor: aSpec color. + widget window: (widget window topLeft extent: aSpec extent). + + self setFrame: aSpec frame in: widget. + + parent ifNotNil:[parent addSubView: widget]. + ^widget! From commits at source.squeak.org Sun May 3 13:16:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 13:16:03 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Morphic-mt.144.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.144.mcz ==================== Summary ==================== Name: ToolBuilder-Morphic-mt.144 Author: mt Time: 3 May 2015, 3:15:54.123 pm UUID: cf322845-a61b-874c-9dc5-872dd0377db1 Ancestors: ToolBuilder-Morphic-mt.143 Adds spacers to morphic toolbuilder. =============== Diff against ToolBuilder-Morphic-mt.143 =============== Item was added: + ----- Method: MorphicToolBuilder>>buildPluggableSpacer: (in category 'widgets required') ----- + buildPluggableSpacer: spec + + | widget | + widget := self spacerClass new. + self register: widget id: spec name. + + widget borderWidth: 0. + widget color: spec color. + widget extent: spec extent. + + self buildHelpFor: widget spec: spec. + + self setFrame: spec frame in: widget. + self setLayoutHintsFor: widget spec: spec. + + parent ifNotNil:[self add: widget to: parent]. + ^widget! Item was added: + ----- Method: MorphicToolBuilder>>spacerClass (in category 'widget classes') ----- + spacerClass + + ^ Morph! From commits at source.squeak.org Sun May 3 13:21:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 13:21:23 2015 Subject: [squeak-dev] The Trunk: Tools-mt.618.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.618.mcz ==================== Summary ==================== Name: Tools-mt.618 Author: mt Time: 3 May 2015, 3:21:02.561 pm UUID: 8343c92d-b4ef-8d4c-9602-3054a12f5ee9 Ancestors: Tools-mt.617 Add a small spacer in front of the "code provenance button" in the optional button pane in code holders. =============== Diff against Tools-mt.617 =============== Item was changed: ----- Method: CodeHolder>>buildOptionalButtonsWith: (in category 'toolbuilder') ----- buildOptionalButtonsWith: builder | panelSpec | panelSpec := builder pluggablePanelSpec new. panelSpec children: OrderedCollection new. self optionalButtonPairs do:[:spec| | buttonSpec | buttonSpec := builder pluggableActionButtonSpec new. buttonSpec model: self. buttonSpec label: spec first. buttonSpec action: spec second. spec second == #methodHierarchy ifTrue:[ buttonSpec color: #inheritanceButtonColor. ]. spec size > 2 ifTrue:[buttonSpec help: spec third]. panelSpec children add: buttonSpec. ]. + "What to show" + panelSpec children add: builder pluggableSpacerSpec new. self addCodeProvenanceButtonTo: panelSpec using: builder. panelSpec layout: #horizontal. "buttons" ^panelSpec! From commits at source.squeak.org Sun May 3 13:25:42 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 13:25:43 2015 Subject: [squeak-dev] The Trunk: Tools-mt.619.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.619.mcz ==================== Summary ==================== Name: Tools-mt.619 Author: mt Time: 3 May 2015, 3:25:22.342 pm UUID: ea1fe725-3b4c-bf47-b12a-3ee9715d392b Ancestors: Tools-mt.618 Now we can open the message names tool from the parts bin again. =============== Diff against Tools-mt.618 =============== Item was changed: ----- Method: MessageNames class>>prototypicalToolWindow (in category 'instance creation') ----- prototypicalToolWindow "Answer an example of myself seen in a tool window, for the benefit of parts-launching tools" + ^ self methodBrowserSearchingFor: ''! - ^ self methodBrowserSearchingFor: nil! From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 13:10:43 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 13:26:09 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.617.mcz In-Reply-To: References: Message-ID: <1430658643397-4823988.post@n4.nabble.com> Thanks! :) And fixed: http://forum.world.st/The-Trunk-Tools-mt-619-mcz-td4823987.html Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Tools-mt-617-mcz-tp4823946p4823988.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 13:11:43 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 13:27:09 2015 Subject: [squeak-dev] Re: The Trunk: ToolBuilder-Kernel-mt.88.mcz In-Reply-To: References: Message-ID: <1430658703829-4823989.post@n4.nabble.com> Now you can start grouping buttons in longer button panes to help users make sense of it more quickly. :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-ToolBuilder-Kernel-mt-88-mcz-tp4823983p4823989.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 13:29:28 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 13:44:55 2015 Subject: [squeak-dev] Changing button groups/order in browsers Message-ID: <1430659768347-4823991.post@n4.nabble.com> Hey! Will somebody start yelling at me if I modify the buttons of system browsers (and code holders) like this: :D Best, Marcel -- View this message in context: http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Sun May 3 14:12:42 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sun May 3 14:12:45 2015 Subject: [squeak-dev] Changing button groups/order in browsers In-Reply-To: <1430659768347-4823991.post@n4.nabble.com> References: <1430659768347-4823991.post@n4.nabble.com> Message-ID: I like that. I was actually experimenting with the same for the ZipArchive tool :-) Karl On Sun, May 3, 2015 at 3:29 PM, Marcel Taeumel < marcel.taeumel@student.hpi.uni-potsdam.de> wrote: > Hey! > > Will somebody start yelling at me if I modify the buttons of system > browsers > (and code holders) like this: > > > > :D > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150503/9e043b21/attachment.htm From commits at source.squeak.org Sun May 3 14:16:51 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 14:16:53 2015 Subject: [squeak-dev] The Trunk: Morphic-kfr.965.mcz Message-ID: Karl Ramberg uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-kfr.965.mcz ==================== Summary ==================== Name: Morphic-kfr.965 Author: kfr Time: 3 May 2015, 4:15:47.389 pm UUID: 3c3fdbae-bbf1-ec4e-824f-886f6753fc96 Ancestors: Morphic-mt.964 A few changes for NewColorPickerMorph so it fits better in properties panes =============== Diff against Morphic-mt.964 =============== Item was changed: ----- Method: NewColorPickerMorph class>>on:originalColor:setColorSelector: (in category 'create') ----- on: objectToHaveItsColorSet originalColor: originalColor setColorSelector: colorSetterSymbol + ^ self - ^ self new setTarget: objectToHaveItsColorSet originalColor: originalColor + setColorSelector: colorSetterSymbol + forPropertiesPanel: false! - setColorSelector: colorSetterSymbol! Item was added: + ----- Method: NewColorPickerMorph class>>on:originalColor:setColorSelector:forPropertiesPanel: (in category 'create') ----- + on: objectToHaveItsColorSet originalColor: originalColor setColorSelector: colorSetterSymbol forPropertiesPanel: aBool + ^ self new + setTarget: objectToHaveItsColorSet + originalColor: originalColor + setColorSelector: colorSetterSymbol + forPropertiesPanel: aBool! Item was added: + ----- Method: NewColorPickerMorph>>setTarget:originalColor:setColorSelector:forPropertiesPanel: (in category 'initialize-release') ----- + setTarget: objectToHaveItsColorSet originalColor: aColor setColorSelector: colorSetterSymbol forPropertiesPanel: aBool + target := objectToHaveItsColorSet. + setColorSelector := colorSetterSymbol. + hsvaMorph selectedColor: aColor. + aBool + ifTrue: [self setupForProperties] + ifFalse: [self setup]! Item was added: + ----- Method: NewColorPickerMorph>>setupForProperties (in category 'initialize-release') ----- + setupForProperties + self + color: (Color white darker) ; + changeTableLayout ; + hResizing: #shrinkWrap ; + vResizing: #shrinkWrap ; + extent: 240@240 ; + addMorphBack: hsvaMorph ; + layoutInset: 4 ; + cellInset: 2.! From commits at source.squeak.org Sun May 3 14:23:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 14:23:27 2015 Subject: [squeak-dev] The Trunk: Morphic-kfr.966.mcz Message-ID: Karl Ramberg uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-kfr.966.mcz ==================== Summary ==================== Name: Morphic-kfr.966 Author: kfr Time: 3 May 2015, 4:21:59.455 pm UUID: e444aa0f-249a-7347-97fd-a68a1bcadebe Ancestors: Morphic-kfr.965 A fix for last commit =============== Diff against Morphic-kfr.965 =============== Item was changed: ----- Method: NewColorPickerMorph class>>on:originalColor:setColorSelector: (in category 'create') ----- on: objectToHaveItsColorSet originalColor: originalColor setColorSelector: colorSetterSymbol ^ self + on: objectToHaveItsColorSet - setTarget: objectToHaveItsColorSet originalColor: originalColor setColorSelector: colorSetterSymbol forPropertiesPanel: false! From commits at source.squeak.org Sun May 3 14:48:10 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 14:48:13 2015 Subject: [squeak-dev] The Trunk: EToys-kfr.125.mcz Message-ID: Karl Ramberg uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-kfr.125.mcz ==================== Summary ==================== Name: EToys-kfr.125 Author: kfr Time: 3 May 2015, 4:47:39.239 pm UUID: e8cd5fc0-7f73-0540-b1b6-65ae43abf6a4 Ancestors: EToys-mt.124 Fix Properties panel for the new color picker morph =============== Diff against EToys-mt.124 =============== Item was changed: ----- Method: GenericPropertiesMorph>>colorPickerFor:getter:setter: (in category 'as yet unclassified') ----- colorPickerFor: target getter: getterSymbol setter: setterSymbol ^ NewColorPickerMorph useIt ifTrue: [ NewColorPickerMorph on: target originalColor: (target perform: getterSymbol) + setColorSelector: setterSymbol + forPropertiesPanel: true + ] - setColorSelector: setterSymbol ] ifFalse: [ ColorPickerMorph new initializeForPropertiesPanel ; target: target ; selector: setterSymbol ; originalColor: (target perform: getterSymbol) ]! Item was changed: ----- Method: ObjectPropertiesMorph>>tgt2ndGradientColor: (in category 'as yet unclassified') ----- tgt2ndGradientColor: aColor + myTarget fillStyle isGradientFill ifFalse: [^Color black]. - myTarget fillStyle lastColor: aColor forMorph: myTarget hand: nil ! From commits at source.squeak.org Sun May 3 15:58:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 15:58:15 2015 Subject: [squeak-dev] The Trunk: Collections-mt.629.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.629.mcz ==================== Summary ==================== Name: Collections-mt.629 Author: mt Time: 3 May 2015, 5:57:18.046 pm UUID: a8c03faf-7161-bf42-8143-7fd4833709e9 Ancestors: Collections-ul.628 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... =============== Diff against Collections-ul.628 =============== Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '"' startingAt: startIndex+attribute size. + stopIndex := aTag findString: '"' startingAt: startIndex+1. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag lookForNewTag escapeNextCharacter tagFound | + lookForNewTag := true. + tagFound := false. + tag := OrderedCollection new. + escapeNextCharacter := false. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + count := count + 1. + + escapeNextCharacter + ifTrue: [string add: character. escapeNextCharacter := false] + ifFalse: [ + character = $\ + ifTrue: [offset := offset + 1. escapeNextCharacter := true] + ifFalse: [ + character = $< ifTrue: [lookForNewTag := false]. + character = $> ifTrue: [lookForNewTag := true]. + + (lookForNewTag and: [character ~= $>]) + ifTrue: [string add: character] + ifFalse: [tag add: character. offset := offset + 1].. + + (tag notEmpty and: [tag last = $>]) ifTrue: [ + "Full tag like or found." + tag second ~= $/ + ifTrue: [self processStartTag: (String withAll: tag)] + ifFalse: [self processEndTag: (String withAll: tag)]. + tagFound := true]]]]. + ! Item was added: + ----- Method: HtmlReadWriter>>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + index := count - offset. + + "Accumulate adjacent tags." + (runStack size > 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + | html | + html := aString. + "" + html := html copyReplaceAll: '&' with: '&'. + html := html copyReplaceAll: '>' with: '>'. + html := html copyReplaceAll: '<' with: '<'. + "" + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. + "" + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. + "" + html := html copyReplaceAll: ' + ' with: '
+ '. + html := html copyReplaceAll: ' ' with: '    '. + "" + stream nextPutAll: html! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + aTextAttribute closeHtmlOn: stream.! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + aTextAttribute openHtmlOn: stream.! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! From commits at source.squeak.org Sun May 3 15:58:47 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 15:58:49 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.241.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.241.mcz ==================== Summary ==================== Name: CollectionsTests-mt.241 Author: mt Time: 3 May 2015, 5:58:35.389 pm UUID: 1c0d39a2-eaa3-ee4b-9ccd-bea100a11c66 Ancestors: CollectionsTests-tfel.240 Tests added for html read-writer. =============== Diff against CollectionsTests-tfel.240 =============== Item was added: + TestCase subclass: #HtmlReadWriterTest + instanceVariableNames: 'readWriter html text' + classVariableNames: '' + poolDictionaries: '' + category: 'CollectionsTests-Text'! Item was added: + ----- Method: HtmlReadWriterTest>>convertHtml: (in category 'running') ----- + convertHtml: anHtmlString + + html := anHtmlString. + text := (readWriter on: html readStream) nextText.! Item was added: + ----- Method: HtmlReadWriterTest>>convertText: (in category 'running') ----- + convertText: aText + + text := aText. + html := String streamContents: [:writeStream | + (readWriter on: writeStream) nextPutText: text].! Item was added: + ----- Method: HtmlReadWriterTest>>setUp (in category 'running') ----- + setUp + + super setUp. + + readWriter := HtmlReadWriter new. + html := ''. + text := '' asText.! Item was added: + ----- Method: HtmlReadWriterTest>>test01Emphasis (in category 'tests') ----- + test01Emphasis + + { + 'Hello, World!!'. + 'Hello, World!!' asText addAttribute: TextEmphasis bold. + + 'Hello, World!!'. + 'Hello, World!!' asText addAttribute: TextEmphasis bold from: 1 to: 5. + } pairsDo: [:expectedHtml :expectedText | + + self convertHtml: expectedHtml. + self assert: expectedText string equals: text string. + self assert: expectedText runs equals: text runs. + + self convertText: expectedText. + self assert: expectedHtml equals: html].! Item was added: + ----- Method: HtmlReadWriterTest>>test02Mixed (in category 'tests') ----- + test02Mixed + "At the moment, the html code generation is kind of verbose..." + + { + 'Hello, World!!'. + 'Hello, World!!' asText + addAttribute: TextEmphasis bold; + addAttribute: TextEmphasis italic from: 8 to: 13. + } pairsDo: [:expectedHtml :expectedText | + + self convertHtml: expectedHtml. + self assert: expectedText string equals: text string. + self assert: expectedText runs equals: text runs. + + self convertText: expectedText. + self assert: expectedHtml equals: html].! Item was added: + ----- Method: HtmlReadWriterTest>>test03FontTag (in category 'tests') ----- + test03FontTag + + { + 'Hello, World!!'. + 'Hello, World!!' asText + addAttribute: (TextColor color: Color yellow). + } pairsDo: [:expectedHtml :expectedText | + + self convertHtml: expectedHtml. + self assert: expectedText string equals: text string. + self assert: expectedText runs equals: text runs. + + self convertText: expectedText. + self assert: expectedHtml equals: html].! From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 15:47:48 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 16:03:15 2015 Subject: [squeak-dev] Re: The Trunk: Collections-mt.629.mcz In-Reply-To: References: Message-ID: <1430668068826-4824022.post@n4.nabble.com> '*Hello*, World!' asTextFromHtml asMorph openInHand. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Collections-mt-629-mcz-tp4824013p4824022.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Sun May 3 17:45:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 17:45:27 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.967.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.967.mcz ==================== Summary ==================== Name: Morphic-mt.967 Author: mt Time: 3 May 2015, 7:44:48.727 pm UUID: 40874e5f-4add-e040-9814-7d102d3a66e5 Ancestors: Morphic-kfr.966 Small fixes in text morphs. =============== Diff against Morphic-kfr.966 =============== Item was changed: ----- Method: PluggableTextMorph>>selectAll (in category 'editor access') ----- selectAll + "Tell my textMorph to select all" - "Tell my textMorph's editor to select all" + textMorph selectAll.! - textMorph editor selectAll! Item was changed: ----- Method: TextMorph>>chooseEmphasis (in category 'editing') ----- chooseEmphasis + self editor changeEmphasisOrAlignment. - self editor changeEmphasis. self updateFromParagraph! Item was changed: ----- Method: TextMorph>>selectAll (in category 'accessing') ----- selectAll + + self selectionChanged. + self editor selectAll. + self selectionChanged.! - self editor selectFrom: 1 to: text size! Item was removed: - ----- Method: TextMorphForEditView>>selectAll (in category 'miscellaneous') ----- - selectAll - "Tell my editor to select all the text" - - self editor selectAll! From commits at source.squeak.org Sun May 3 18:50:01 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 18:50:02 2015 Subject: [squeak-dev] The Trunk: Collections-mt.630.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.630.mcz ==================== Summary ==================== Name: Collections-mt.630 Author: mt Time: 3 May 2015, 8:49:41.443 pm UUID: c6ffc6e0-978d-da42-acdb-4917691a695c Ancestors: Collections-mt.629 HTML escaping added to html read/writer =============== Diff against Collections-mt.629 =============== Item was changed: ----- Method: HtmlReadWriter>>processEndTag: (in category 'reading') ----- processEndTag: aTag | index | index := count - offset. + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + "De-Accumulate adjacent tags." runStack top at: 4 put: runStack top fourth - 1. runStack top fourth > 0 ifTrue: [^ self "not yet"]. self processRunStackTop. runStack pop. runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processHtmlEscape: (in category 'reading') ----- + processHtmlEscape: aString + + (String htmlEntities at: (aString copyFrom: 2 to: aString size - 1) ifAbsent: []) + ifNotNil: [:char | + string add: char. + count := count + 1].! Item was changed: ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- processNextTag + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid | - | tag lookForNewTag escapeNextCharacter tagFound | lookForNewTag := true. + lookForHtmlEscape := false. tagFound := false. tag := OrderedCollection new. + htmlEscape := OrderedCollection new. - escapeNextCharacter := false. [stream atEnd not and: [tagFound not]] whileTrue: [ | character | character := stream next. + valid := (#(10 13) includes: character asciiValue) not. count := count + 1. + character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [lookForHtmlEscape := true]. - escapeNextCharacter - ifTrue: [string add: character. escapeNextCharacter := false] - ifFalse: [ - character = $\ - ifTrue: [offset := offset + 1. escapeNextCharacter := true] - ifFalse: [ - character = $< ifTrue: [lookForNewTag := false]. - character = $> ifTrue: [lookForNewTag := true]. + lookForNewTag + ifTrue: [ + lookForHtmlEscape + ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] + ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] + ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + + character = $> ifTrue: [ + lookForNewTag := true. + "Full tag like or found." + tag second ~= $/ + ifTrue: [self processStartTag: (String withAll: tag)] + ifFalse: [self processEndTag: (String withAll: tag)]. + tagFound := true]. + + character = $; ifTrue: [ + lookForHtmlEscape := false. + self processHtmlEscape: (String withAll: htmlEscape). + htmlEscape := OrderedCollection new]]. - (lookForNewTag and: [character ~= $>]) - ifTrue: [string add: character] - ifFalse: [tag add: character. offset := offset + 1].. - - (tag notEmpty and: [tag last = $>]) ifTrue: [ - "Full tag like or found." - tag second ~= $/ - ifTrue: [self processStartTag: (String withAll: tag)] - ifFalse: [self processEndTag: (String withAll: tag)]. - tagFound := true]]]]. ! Item was changed: ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- processStartTag: aTag | index | index := count - offset. + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + "Accumulate adjacent tags." (runStack size > 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) ifTrue: [ runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" ^self]. self processRunStackTop. "Remove start/end info to reuse attributes later." runStack top at: 2 put: nil. runStack top at: 3 put: nil. "Copy attr list and add new attr." runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was changed: ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- writeContent: aString + aString do: [:char | + (#(10 13) includes: char asciiValue) + ifTrue: [stream nextPutAll: '
'; cr] + ifFalse: [char = Character tab + ifTrue: [stream nextPutAll: '    '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]].! - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - stream nextPutAll: html! Item was changed: ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- writeEndTagFor: aTextAttribute + [aTextAttribute closeHtmlOn: stream] + on: MessageNotUnderstood do: []! - aTextAttribute closeHtmlOn: stream.! Item was changed: ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- writeStartTagFor: aTextAttribute + [aTextAttribute openHtmlOn: stream] + on: MessageNotUnderstood do: [].! - aTextAttribute openHtmlOn: stream.! Item was added: + ----- Method: String class>>htmlEntities (in category 'accessing') ----- + htmlEntities + + ^ HtmlEntities! From commits at source.squeak.org Sun May 3 18:50:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 18:50:48 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.242.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.242.mcz ==================== Summary ==================== Name: CollectionsTests-mt.242 Author: mt Time: 3 May 2015, 8:50:35.161 pm UUID: 988cc75a-c808-c040-b94c-e8f9cf0623d7 Ancestors: CollectionsTests-mt.241 More tests for html read/writer =============== Diff against CollectionsTests-mt.241 =============== Item was added: + ----- Method: HtmlReadWriterTest>>test04LineBreaks (in category 'tests') ----- + test04LineBreaks + + { + 'Hello, World!!
+ '. + 'Hello, World!! + ' asText. + + 'Hello, World!!
+
'. + 'Hello, World!! + ' asText + addAttribute: TextEmphasis bold from: 8 to: 14. + } pairsDo: [:expectedHtml :expectedText | + + self convertHtml: expectedHtml. + self assert: expectedText string equals: text string. + self assert: expectedText runs equals: text runs. + + self convertText: expectedText. + self assert: expectedHtml equals: html. + + self convertHtml: html. + self convertText: text. + self assert: expectedHtml equals: html. + + + ].! Item was added: + ----- Method: HtmlReadWriterTest>>test05Escaping (in category 'tests') ----- + test05Escaping + + { + 'Morph>>#drawOn:'. + 'Morph>>#drawOn:' asText addAttribute: TextEmphasis bold. + } pairsDo: [:expectedHtml :expectedText | + + self convertHtml: expectedHtml. + self assert: expectedText string equals: text string. + self assert: expectedText runs equals: text runs. + + self convertText: expectedText. + self assert: expectedHtml equals: html].! From commits at source.squeak.org Sun May 3 20:38:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 20:38:57 2015 Subject: [squeak-dev] The Trunk: Collections-mt.631.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.631.mcz ==================== Summary ==================== Name: Collections-mt.631 Author: mt Time: 3 May 2015, 10:38:38.118 pm UUID: 0b21fbfc-3cd6-8f45-bf1a-d7e3c5e5c107 Ancestors: Collections-mt.630 HtmlReadWriter: support for comments added, list of ignored tags added =============== Diff against Collections-mt.630 =============== Item was added: + ----- Method: HtmlReadWriter>>ignoredTags (in category 'accessing') ----- + ignoredTags + "Because we cannot process all of them." + + ^ #(body script table tr td ul ol li form select option input)! Item was added: + ----- Method: HtmlReadWriter>>isTagIgnored: (in category 'testing') ----- + isTagIgnored: aTag + + | space t | + space := aTag indexOf: Character space. + t := space > 0 + ifTrue: [aTag copyFrom: 2 to: space - 1] + ifFalse: [aTag copyFrom: 2 to: aTag size - 1]. + ^ self ignoredTags includes: t! Item was changed: ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- mapATag: aTag | result startIndex stopIndex attribute | result := OrderedCollection new. + + Transcript showln: aTag. "
" attribute := 'href'. startIndex := aTag findString: attribute. startIndex > 0 ifTrue: [ + startIndex := aTag findString: '=' startingAt: startIndex+attribute size. + stopIndex := aTag findString: ' ' startingAt: startIndex+1. + stopIndex = 0 ifTrue: [ + stopIndex := aTag findString: '>' startingAt: startIndex+1]. - startIndex := aTag findString: '"' startingAt: startIndex+attribute size. - stopIndex := aTag findString: '"' startingAt: startIndex+1. - result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + (aTag at: startIndex + 1) = $" + ifTrue: [startIndex := startIndex + 1]. + (aTag at: stopIndex - 1) = $" + ifTrue: [stopIndex := stopIndex - 1]. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + ^ result! Item was changed: ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- mapTagToAttribute: aTag aTag = '' ifTrue: [^ {TextEmphasis bold}]. aTag = '' ifTrue: [^ {TextEmphasis italic}]. aTag = '' ifTrue: [^ {TextEmphasis underlined}]. "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." (aTag beginsWith: '>nextText (in category 'accessing') ----- nextText count := 0. offset := 0. "To ignore characters in the input string that are used by tags." runStack := Stack new. runArray := RunArray new. string := OrderedCollection new. "{text attributes. start index. end index. number of open tags}" runStack push: {OrderedCollection new. 1. nil. 0}. [stream atEnd] whileFalse: [self processNextTag]. self processRunStackTop. "Add last run." string := String withAll: string. + runArray coalesce. ^ Text string: string runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processComment: (in category 'reading') ----- + processComment: aComment + ! Item was added: + ----- Method: HtmlReadWriter>>processEmptyTag: (in category 'reading') ----- + processEmptyTag: aTag + + (aTag beginsWith: '>processEndTag: (in category 'reading') ----- processEndTag: aTag | index | index := count - offset. + (self ignoredTags includes: (aTag copyFrom: 3 to: aTag size -1)) + ifTrue: [^ self]. + - aTag = '
' ifTrue: [ - string add: Character cr. - count := count + 1. - ^ self]. - "De-Accumulate adjacent tags." runStack top at: 4 put: runStack top fourth - 1. runStack top fourth > 0 ifTrue: [^ self "not yet"]. self processRunStackTop. runStack pop. runStack top at: 2 put: index + 1.! Item was changed: ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- processNextTag + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid inComment | - | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid | lookForNewTag := true. lookForHtmlEscape := false. tagFound := false. tag := OrderedCollection new. htmlEscape := OrderedCollection new. + inComment := false. [stream atEnd not and: [tagFound not]] whileTrue: [ | character | character := stream next. valid := (#(10 13) includes: character asciiValue) not. count := count + 1. character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [ + inComment ifFalse: [lookForHtmlEscape := true]]. - character = $& ifTrue: [lookForHtmlEscape := true]. lookForNewTag ifTrue: [ lookForHtmlEscape ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + inComment := ((lookForNewTag not and: [tag size >= 4]) + and: [tag beginsWith: '') not]. + + ((character = $> and: [inComment not]) and: [lookForNewTag not]) ifTrue: [ - character = $> ifTrue: [ lookForNewTag := true. + (tag beginsWith: ' or
found." - tag second ~= $/ - ifTrue: [self processStartTag: (String withAll: tag)] - ifFalse: [self processEndTag: (String withAll: tag)]. tagFound := true]. + (((character = $; and: [lookForNewTag]) + and: [htmlEscape notEmpty]) and: [htmlEscape first = $&]) ifTrue: [ + lookForHtmlEscape := false. + self processHtmlEscape: (String withAll: htmlEscape). + htmlEscape := OrderedCollection new]]. - character = $; ifTrue: [ - lookForHtmlEscape := false. - self processHtmlEscape: (String withAll: htmlEscape). - htmlEscape := OrderedCollection new]]. ! Item was changed: ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- processStartTag: aTag | index | + (self isTagIgnored: aTag) ifTrue: [^ self]. + index := count - offset. + - aTag = '
' ifTrue: [ string add: Character cr. count := count + 1. ^ self]. + (aTag beginsWith: ' 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) ifTrue: [ runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" ^self]. self processRunStackTop. "Remove start/end info to reuse attributes later." runStack top at: 2 put: nil. runStack top at: 3 put: nil. "Copy attr list and add new attr." runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! From commits at source.squeak.org Sun May 3 20:39:37 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 20:39:38 2015 Subject: [squeak-dev] The Trunk: CollectionsTests-mt.243.mcz Message-ID: Marcel Taeumel uploaded a new version of CollectionsTests to project The Trunk: http://source.squeak.org/trunk/CollectionsTests-mt.243.mcz ==================== Summary ==================== Name: CollectionsTests-mt.243 Author: mt Time: 3 May 2015, 10:39:28.204 pm UUID: 1411adb4-9969-694c-9904-5f4abac42c5e Ancestors: CollectionsTests-mt.242 test for parsing comments in html read/writer added =============== Diff against CollectionsTests-mt.242 =============== Item was added: + ----- Method: HtmlReadWriterTest>>test06Comments (in category 'tests') ----- + test06Comments + + | expectedText | + expectedText := 'Hello & World!!' asText + addAttribute: TextEmphasis bold. + + self convertHtml: ' + JUST!! &&;; a COMMENT!! --> + Hello & World!!'. + + self assert: expectedText string equals: text string. + self assert: expectedText runs equals: text runs.! From commits at source.squeak.org Sun May 3 20:40:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 20:40:34 2015 Subject: [squeak-dev] The Trunk: HelpSystem-Core-mt.73.mcz Message-ID: Marcel Taeumel uploaded a new version of HelpSystem-Core to project The Trunk: http://source.squeak.org/trunk/HelpSystem-Core-mt.73.mcz ==================== Summary ==================== Name: HelpSystem-Core-mt.73 Author: mt Time: 3 May 2015, 10:40:26.596 pm UUID: fbfe2a9b-a41b-5f4d-b5de-6ec6f8f7fc73 Ancestors: HelpSystem-Core-kfr.72 Use HtmlReadWriter for parsing html help topics. =============== Diff against HelpSystem-Core-kfr.72 =============== Item was changed: ----- Method: HtmlHelpTopic>>contents (in category 'accessing') ----- contents | start end | start := (self document findString: '' startingAt: start) + 1. end := self document findString: '' startingAt: start. start > end ifTrue: [^ self document]. + ^ ((self document copyFrom: start to: end - 1) + copyReplaceAll: String cr with: '
') + asTextFromHtml! - ^ (self document copyFrom: start to: end - 1) asUnHtml withBlanksTrimmed! From marcel.taeumel at student.hpi.uni-potsdam.de Sun May 3 20:26:32 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Sun May 3 20:42:03 2015 Subject: [squeak-dev] Re: The Trunk: HelpSystem-Core-mt.73.mcz In-Reply-To: References: Message-ID: <1430684792826-4824062.post@n4.nabble.com> Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-HelpSystem-Core-mt-73-mcz-tp4824061p4824062.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From tim at rowledge.org Sun May 3 20:43:34 2015 From: tim at rowledge.org (tim Rowledge) Date: Sun May 3 20:43:39 2015 Subject: [squeak-dev] The Trunk: HelpSystem-Core-mt.73.mcz In-Reply-To: <1430684792826-4824062.post@n4.nabble.com> References: <1430684792826-4824062.post@n4.nabble.com> Message-ID: <4C6BDAC4-2203-4BC3-A3EF-E4F757EBECBF@rowledge.org> On 03-05-2015, at 1:26 PM, Marcel Taeumel wrote: > Looking good there. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: TOAC: Turn Off Air Conditioner From eliot.miranda at gmail.com Sun May 3 20:44:29 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun May 3 20:44:35 2015 Subject: [squeak-dev] The Trunk: Collections-tfel.623.mcz In-Reply-To: References: Message-ID: Hi Levente, On May 3, 2015, at 5:12 AM, Levente Uzonyi wrote: > On Fri, 1 May 2015, commits@source.squeak.org wrote: > >> Tim Felgentreff uploaded a new version of Collections to project The Trunk: >> http://source.squeak.org/trunk/Collections-tfel.623.mcz >> >> ==================== Summary ==================== >> >> Name: Collections-tfel.623 >> Author: tfel >> Time: 1 May 2015, 11:06:35.625 am >> UUID: baf2902d-52b9-2442-a513-8a5a6ff0ce30 >> Ancestors: Collections-nice.622 >> >> fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 > > If I'm not mistaken, this is the slang code that gets compiled to C. Does slang support #max:? Yes > > Levente > >> >> =============== Diff against Collections-nice.622 =============== >> >> Item was changed: >> ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- >> findSubstring: key in: body startingAt: start matchTable: matchTable >> "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. >> >> The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." >> | index | >> >> >> >> >> >> key size = 0 ifTrue: [^ 0]. >> + (start max: 1) to: body size - key size + 1 do: >> - start to: body size - key size + 1 do: >> [:startIndex | >> index := 1. >> [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) >> = (matchTable at: (key at: index) asciiValue + 1)] >> whileTrue: >> [index = key size ifTrue: [^ startIndex]. >> index := index+1]]. >> ^ 0 >> " >> ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 >> ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 >> ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 >> ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 >> ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 >> "! > From commits at source.squeak.org Sun May 3 21:55:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 3 21:55:08 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150503215505.27717.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008221.html Name: Multilingual-ul.209 Ancestors: Multilingual-ul.208 Refactored unicode data parsing. Case conversion (ToUpper and ToLower) is parsed from UnicodeData.txt instead of CaseFolding.txt. Reinitialize both CaseFolding and CompositionMapping in the postscript. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008222.html Name: Multilingual-ul.208 Ancestors: Multilingual-ul.206 Improved Unicode caseMappings: - Don't overwrite an existing mapping, because that leads to problems (like (Unicode toUppercaseCode: $k asciiValue) = 8490) - Use PluggableDictionary class >> #integerDictionary for better lookup performance (~+16%), and compaction resistance (done at every release). - Compact the dictionaries before saving. - Save the new dictionaries atomically. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008223.html Name: MorphicExtras-nice.163 Ancestors: MorphicExtras-mt.162 Avoid using roundTo: aFloat if it's just for printing. Why? (0.3 roundTo: 0.1) printString -> '0.30000000000000004' ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008224.html Name: Tools-mt.616 Ancestors: Tools-mt.615 Fixed wrong order of buttons in pre-debug window. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008225.html Name: Morphic-mt.960 Ancestors: Morphic-kfr.959 Dead code removed from slider. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008226.html Name: ToolBuilder-Kernel-mt.87 Ancestors: ToolBuilder-Kernel-mt.86 Added resizing policies to layout hints. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008227.html Name: ToolBuilder-Morphic-mt.143 Ancestors: ToolBuilder-Morphic-mt.142 Honor custom resizing policies. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008228.html Name: Kernel-mt.924 Ancestors: Kernel-nice.923 ValueHolder: Only notify about changed contents if contents actually changed. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008229.html Name: Morphic-mt.961 Ancestors: Morphic-mt.960 Fixed shrinkWrap-bug in buttons. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008230.html Name: Morphic-mt.962 Ancestors: Morphic-mt.961 Never share the text instance between text morph and model. Change handling can break otherwise if that text instance will be referenced in the model. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008231.html Name: ST80-mt.184 Ancestors: ST80-mt.183 Added some missing stuff due to changes in Morphic land. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008232.html Name: Morphic-mt.963 Ancestors: Morphic-mt.962 Removed hard-coded extent of 16 at 16 for non-shrinkwrapped buttons when calculating the minimum extent. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008233.html Name: Tools-mt.617 Ancestors: Tools-mt.616 "Message Names" tool refactored. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008234.html Name: Collections-ul.627 Ancestors: Collections-mt.626, Collections-ul.624 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008235.html Name: Collections-ul.628 Ancestors: Collections-ul.627, Collections-ul.625 Merged Collections-ul.625. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008236.html Name: Morphic-mt.964 Ancestors: Morphic-mt.963 Moved specialized list morph for message categories into deprecation. All browsers have regular lists morphs--even for message category lists. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008237.html Name: 46Deprecated-mt.2 Ancestors: 46Deprecated-mt.1 Added a widget that was once used for showing message category lists. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008238.html Name: ToolBuilder-Kernel-mt.88 Ancestors: ToolBuilder-Kernel-mt.87 Added support for spacers in tool builder. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008239.html Name: ToolBuilder-MVC-mt.42 Ancestors: ToolBuilder-MVC-mt.41 A simple implementation for spacers. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008240.html Name: ToolBuilder-Morphic-mt.144 Ancestors: ToolBuilder-Morphic-mt.143 Adds spacers to morphic toolbuilder. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008241.html Name: Tools-mt.618 Ancestors: Tools-mt.617 Add a small spacer in front of the "code provenance button" in the optional button pane in code holders. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008242.html Name: Tools-mt.619 Ancestors: Tools-mt.618 Now we can open the message names tool from the parts bin again. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008243.html Name: Morphic-kfr.965 Ancestors: Morphic-mt.964 A few changes for NewColorPickerMorph so it fits better in properties panes ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008244.html Name: Morphic-kfr.966 Ancestors: Morphic-kfr.965 A fix for last commit ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008245.html Name: EToys-kfr.125 Ancestors: EToys-mt.124 Fix Properties panel for the new color picker morph ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008246.html Name: Collections-mt.629 Ancestors: Collections-ul.628 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008247.html Name: CollectionsTests-mt.241 Ancestors: CollectionsTests-tfel.240 Tests added for html read-writer. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008248.html Name: Morphic-mt.967 Ancestors: Morphic-kfr.966 Small fixes in text morphs. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008249.html Name: Collections-mt.630 Ancestors: Collections-mt.629 HTML escaping added to html read/writer ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008250.html Name: CollectionsTests-mt.242 Ancestors: CollectionsTests-mt.241 More tests for html read/writer ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008251.html Name: Collections-mt.631 Ancestors: Collections-mt.630 HtmlReadWriter: support for comments added, list of ignored tags added ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008252.html Name: CollectionsTests-mt.243 Ancestors: CollectionsTests-mt.242 test for parsing comments in html read/writer added ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008253.html Name: HelpSystem-Core-mt.73 Ancestors: HelpSystem-Core-kfr.72 Use HtmlReadWriter for parsing html help topics. ============================================= From dnorton at mindspring.com Sun May 3 23:27:38 2015 From: dnorton at mindspring.com (Dan Norton) Date: Sun May 3 23:27:43 2015 Subject: [squeak-dev] disableProgrammerFacilities Message-ID: <5546AEEA.19015.190244A@dnorton.mindspring.com> 'Preferences disableProgrammerFacilities' doesn't do much, currently :) It would be good to have this disable the IDE at some point. It does seem to kill commands cmd-d and cmd-c but the browser et al remain available. From asqueaker at gmail.com Mon May 4 00:52:10 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 00:52:14 2015 Subject: [squeak-dev] The Trunk: Tools-mt.616.mcz In-Reply-To: <5545c757.e21a340a.7514.ffff9ecaSMTPIN_ADDED_MISSING@mx.google.com> References: <5545c757.e21a340a.7514.ffff9ecaSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Thanks. On Sun, May 3, 2015 at 1:59 AM, wrote: > Marcel Taeumel uploaded a new version of Tools to project The Trunk: > http://source.squeak.org/trunk/Tools-mt.616.mcz > > ==================== Summary ==================== > > Name: Tools-mt.616 > Author: mt > Time: 3 May 2015, 8:59:08.565 am > UUID: d7973151-c795-fb4c-9d1f-daab9ef068e6 > Ancestors: Tools-mt.615 > > Fixed wrong order of buttons in pre-debug window. > > =============== Diff against Tools-mt.615 =============== > > Item was changed: > ----- Method: Debugger>>buildNotifierWith:label:message: (in category 'toolbuilder') ----- > buildNotifierWith: builder label: label message: messageString > | windowSpec listSpec textSpec panelSpec quads | > windowSpec := builder pluggableWindowSpec new > model: self; > extent: self initialExtentForNotifier; > label: label; > children: OrderedCollection new. > > panelSpec := builder pluggablePanelSpec new. > panelSpec children: OrderedCollection new. > quads := self preDebugButtonQuads. > (self interruptedContext selector == #doesNotUnderstand:) ifTrue: [ > quads := quads copyWith: > { 'Create'. #createMethod. #magenta. 'create the missing method' } > ]. > (#(#notYetImplemented #shouldBeImplemented #requirement) includes: self interruptedContext selector) ifTrue: [ > quads := quads copyWith: > { 'Create'. #createImplementingMethod. #magenta. 'implement the marked method' } > ]. > (self interruptedContext selector == #subclassResponsibility) ifTrue: [ > quads := quads copyWith: > { 'Create'. #createOverridingMethod. #magenta. 'create the missing overriding method' } > ]. > quads do:[:spec| | buttonSpec | > buttonSpec := builder pluggableButtonSpec new. > buttonSpec model: self. > buttonSpec label: spec first. > buttonSpec action: spec second. > buttonSpec help: spec fourth. > - buttonSpec frame: self preDebugButtonQuadFrame. > panelSpec children add: buttonSpec. > ]. > panelSpec layout: #horizontal. "buttons" > panelSpec frame: self preDebugButtonQuadFrame. > windowSpec children add: panelSpec. > > Preferences eToyFriendly | messageString notNil ifFalse:[ > listSpec := builder pluggableListSpec new. > listSpec > model: self; > list: #contextStackList; > getIndex: #contextStackIndex; > setIndex: #debugAt:; > frame: self contextStackFrame. > windowSpec children add: listSpec. > ] ifTrue:[ > message := messageString. > textSpec := builder pluggableTextSpec new. > textSpec > model: self; > getText: #preDebugMessageString; > setText: nil; > selection: nil; > menu: #debugProceedMenu:; > frame: self contextStackFrame. > windowSpec children add: textSpec. > ]. > > ^windowSpec! > > From asqueaker at gmail.com Mon May 4 01:01:42 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 01:01:45 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: On Sun, May 3, 2015 at 6:50 AM, karl ramberg wrote: > I mean this more like: when we have separate preferences for every widget it > will be hard,confusing and tedious to hunt down every setting for color and > corner rounding etc. to change the look of the system. > Even if the PreferenceBrowser access them all, it will become overwhelming > with several hundred preferences It might help to understand what you want to do. You mentioned hunting down every setting for color, etc., so what about that DictionaryOfPreferences, isn't that it? Isn't that the place where every pref in the system is collected up together? From asqueaker at gmail.com Mon May 4 01:07:59 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 01:08:01 2015 Subject: [squeak-dev] Changing button groups/order in browsers In-Reply-To: References: <1430659768347-4823991.post@n4.nabble.com> Message-ID: On Sun, May 3, 2015 at 9:12 AM, karl ramberg wrote: > I like that. If you're referring to the | Instance | Class | |?| buttons, I kind of do too.. :) > I was actually experimenting with the same for the ZipArchive tool :-) > > Karl > > On Sun, May 3, 2015 at 3:29 PM, Marcel Taeumel > wrote: >> >> Hey! >> >> Will somebody start yelling at me if I modify the buttons of system >> browsers >> (and code holders) like this: >> >> >> >> :D >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: >> http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> > > > > From asqueaker at gmail.com Mon May 4 01:11:49 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 01:11:52 2015 Subject: [squeak-dev] Re: The Trunk: HelpSystem-Core-mt.73.mcz In-Reply-To: <1430684792826-4824062.post@n4.nabble.com> References: <1430684792826-4824062.post@n4.nabble.com> Message-ID: Oh cool... :) On Sun, May 3, 2015 at 3:26 PM, Marcel Taeumel wrote: > > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-HelpSystem-Core-mt-73-mcz-tp4824061p4824062.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From marcel.taeumel at student.hpi.uni-potsdam.de Mon May 4 05:26:51 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Mon May 4 05:42:23 2015 Subject: [squeak-dev] Re: disableProgrammerFacilities In-Reply-To: <5546AEEA.19015.190244A@dnorton.mindspring.com> References: <5546AEEA.19015.190244A@dnorton.mindspring.com> Message-ID: <1430717211830-4824141.post@n4.nabble.com> Interesting. :) Can elaborate on what it means to "disable the IDE" in terms of Squeak? - System Browser, Inspctor, Explorer, Message Set, ... - Morphic Halos, Meta menus - Distinct keyboard shortcuts such as CMD+P, CMD+D, ... - Shrinking down the world menu to Transcript/Save/Quit - ... Is it a deployment scenario? What might happen if a debugger wants to pop up? ...What does eToys do? =) Best, Marcel -- View this message in context: http://forum.world.st/disableProgrammerFacilities-tp4824089p4824141.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From herbertkoenig at gmx.net Mon May 4 06:30:17 2015 From: herbertkoenig at gmx.net (=?windows-1252?Q?Herbert_K=F6nig?=) Date: Mon May 4 06:30:22 2015 Subject: [squeak-dev] Re: disableProgrammerFacilities In-Reply-To: <1430717211830-4824141.post@n4.nabble.com> References: <5546AEEA.19015.190244A@dnorton.mindspring.com> <1430717211830-4824141.post@n4.nabble.com> Message-ID: <554711F9.3030408@gmx.net> Hi, in 3.8 times I used a changeset (SqueakLockdown-nk.1.cs) from 3.4 times to create deployment images. After loading the changeset and doing some magic with addToStartupList you'd get an image that behaved like a conventional application. There would be a pre debug window with the only option to close it. Today I'll check if the changeset still works in 4.5 though I have some doubts. Below I will paste the comment of the cs. Cheers, Herbert 'From Squeak3.4 of 1 March 2003 [latest update: #5170] on 26 March 2003 at 7:07:40 pm'! "Change Set: SqueakLockdown-nk Date: 26 March 2003 Author: Ned Konz 26 Mar 03: Minor change for 3.4, made it append to existing personal menu instead. Also added disabling of readDocumentAtStartup. 20 Oct 02: Fixed bug that allowed cmd-shift-W to pop up World menu when locked down. This change set makes it easier to lock down an image for application delivery. By executing: Preferences disableProgrammerFacilities from your personalized World menu and saving the locked image under a new name, the following features are disabled: * Halos * Meta and Debug menus * Command keys in world * Command-dot interrupts * Debuggers (though notifiers will still come up) * World menu (from mouse or key) * Command keys other than editing & cursor in text * Reading scripts/projects at startup. The yellow-button menus in text panes will still come up. It is assumed that text panes in your app will have their own yellow-button menus. Two existing preferences have been made available in the Preferences tool: cmdKeysInText -- enables the use of many cmd (or alt) keys in text editors cmdGesturesEnabled -- enables halos, debug menus, etc. Another two new preferences have been added: appendToErrorLog -- appends to the error log rather than replacing it noDebugButton -- suppress the ability to open a debugger from a notifier You can add this to your personalized World menu: aMenu add: 'disable pgrmr' target: Preferences action: #disableProgrammerFacilities. Or you can add: Preferences disableProgrammerFacilities to your do... menu list. Am 04.05.2015 um 07:26 schrieb Marcel Taeumel: > Interesting. :) Can elaborate on what it means to "disable the IDE" in terms > of Squeak? > > - System Browser, Inspctor, Explorer, Message Set, ... > - Morphic Halos, Meta menus > - Distinct keyboard shortcuts such as CMD+P, CMD+D, ... > - Shrinking down the world menu to Transcript/Save/Quit > - ... > > Is it a deployment scenario? What might happen if a debugger wants to pop > up? > > ...What does eToys do? =) > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/disableProgrammerFacilities-tp4824089p4824141.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From marcel.taeumel at student.hpi.uni-potsdam.de Mon May 4 09:46:13 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Mon May 4 10:01:49 2015 Subject: [squeak-dev] MorphicEvent >> timeStamp ??? Message-ID: <1430732773838-4824194.post@n4.nabble.com> Hi, there! In what format is the time stamp of events? It's not Time millisecondClockValue... Print it: self currentEvent timeStamp No, print that: Time millisecondClockValue. Best, Marcel -- View this message in context: http://forum.world.st/MorphicEvent-timeStamp-tp4824194.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From stephan at stack.nl Mon May 4 11:47:05 2015 From: stephan at stack.nl (Stephan Eggermont) Date: Mon May 4 11:47:24 2015 Subject: [squeak-dev] Re: Using Artefact PDF library in Squeak In-Reply-To: References: <5544fd9d.619b340a.67a2.ffffadd8SMTPIN_ADDED_MISSING@mx.google.com> <0EE454FD-FF87-4E81-8305-EF75BDCDB07E@gmail.com> Message-ID: On 02/05/15 21:40, Levente Uzonyi wrote: > > I remember #asDictionary now. This is what happens when you don't want > caseOf: and caseOf:otherwise: be in your language: > > ^PDFDataSymbol symbol: ({ #singlePage->'SinglePage' . > #continuousPages->'OneColumn' . #twoPages->'TwoColumnLeft' } > asDictionary at: self displayLayout). That is ugly, I concur. What concrete action do you propose? Stephan From timfelgentreff at gmail.com Mon May 4 12:41:23 2015 From: timfelgentreff at gmail.com (timfelgentreff) Date: Mon May 4 12:56:57 2015 Subject: [squeak-dev] Re: Changing button groups/order in browsers In-Reply-To: References: <1430659768347-4823991.post@n4.nabble.com> Message-ID: <1430743283559-4824268.post@n4.nabble.com> While we're at it, can we change the round source button? Make it look like the others, but maybe with a downwards triangle or some such to indicate it's actually a dropdown? or make it actually look like a drop down? Now it just looks out of place -- View this message in context: http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991p4824268.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Mon May 4 13:06:46 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon May 4 13:06:49 2015 Subject: [squeak-dev] MorphicEvent >> timeStamp ??? In-Reply-To: <1430732773838-4824194.post@n4.nabble.com> References: <1430732773838-4824194.post@n4.nabble.com> Message-ID: Looks like it is: { self currentEvent timeStamp. Time millisecondClockValue } "==> #(88293652 88293660)" Levente On Mon, 4 May 2015, Marcel Taeumel wrote: > Hi, there! > > In what format is the time stamp of events? It's not Time > millisecondClockValue... > > Print it: > > self currentEvent timeStamp > > No, print that: > > Time millisecondClockValue. > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/MorphicEvent-timeStamp-tp4824194.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From karlramberg at gmail.com Mon May 4 14:15:56 2015 From: karlramberg at gmail.com (karl ramberg) Date: Mon May 4 14:15:59 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: Hi, I guess I am more questioning the sheer number of preferences. There are around 300 preferences in the system now. Many of them I think can be deprecated. Karl On Mon, May 4, 2015 at 3:01 AM, Chris Muller wrote: > On Sun, May 3, 2015 at 6:50 AM, karl ramberg > wrote: > > I mean this more like: when we have separate preferences for every > widget it > > will be hard,confusing and tedious to hunt down every setting for color > and > > corner rounding etc. to change the look of the system. > > Even if the PreferenceBrowser access them all, it will become > overwhelming > > with several hundred preferences > > It might help to understand what you want to do. You mentioned > hunting down every setting for color, etc., so what about that > DictionaryOfPreferences, isn't that it? Isn't that the place where > every pref in the system is collected up together? > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/5e0dcf72/attachment.htm From karlramberg at gmail.com Mon May 4 14:28:15 2015 From: karlramberg at gmail.com (karl ramberg) Date: Mon May 4 14:28:19 2015 Subject: [squeak-dev] Re: Changing button groups/order in browsers In-Reply-To: <1430743283559-4824268.post@n4.nabble.com> References: <1430659768347-4823991.post@n4.nabble.com> <1430743283559-4824268.post@n4.nabble.com> Message-ID: I was wondering about the senders and implementors buttons. It would be nice to be able to chose either local or global scope. I'm not sure we have a nice button widget that can do that. Karl On Mon, May 4, 2015 at 2:41 PM, timfelgentreff wrote: > While we're at it, can we change the round source button? Make it look like > the others, but maybe with a downwards triangle or some such to indicate > it's actually a dropdown? or make it actually look like a drop down? Now it > just looks out of place > > > > -- > View this message in context: > http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991p4824268.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/5c869016/attachment-0001.htm From karlramberg at gmail.com Mon May 4 14:31:27 2015 From: karlramberg at gmail.com (karl ramberg) Date: Mon May 4 14:31:31 2015 Subject: [squeak-dev] Re: Changing button groups/order in browsers In-Reply-To: References: <1430659768347-4823991.post@n4.nabble.com> <1430743283559-4824268.post@n4.nabble.com> Message-ID: Dropdown /split button I guess is the name of said button On Mon, May 4, 2015 at 4:28 PM, karl ramberg wrote: > I was wondering about the senders and implementors buttons. It would be > nice to be able to chose either local or global scope. I'm not sure we have > a nice button widget that can do that. > > Karl > > On Mon, May 4, 2015 at 2:41 PM, timfelgentreff > wrote: > >> While we're at it, can we change the round source button? Make it look >> like >> the others, but maybe with a downwards triangle or some such to indicate >> it's actually a dropdown? or make it actually look like a drop down? Now >> it >> just looks out of place >> >> >> >> -- >> View this message in context: >> http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991p4824268.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/6e52c9a9/attachment.htm From herbertkoenig at gmx.net Mon May 4 15:16:01 2015 From: herbertkoenig at gmx.net (=?windows-1252?Q?Herbert_K=F6nig?=) Date: Mon May 4 15:16:04 2015 Subject: [squeak-dev] Re: disableProgrammerFacilities In-Reply-To: <554711F9.3030408@gmx.net> References: <5546AEEA.19015.190244A@dnorton.mindspring.com> <1430717211830-4824141.post@n4.nabble.com> <554711F9.3030408@gmx.net> Message-ID: <55478D31.6080100@gmx.net> Am 04.05.2015 um 08:30 schrieb Herbert K?nig: > Hi, > in 3.8 times I used a changeset (SqueakLockdown-nk.1.cs) from 3.4 > times to create deployment images. After loading the changeset and > doing some magic with addToStartupList you'd get an image that behaved > like a conventional application. There would be a pre debug window > with the only option to close it. > Ok, here goes: Without the changeset only command keys are disabled. Squeak 4.5-13680: UTF-Textconverter complains if I drop the cs into the image. But I can file in everything from the changes browser. Squeak 4.5-1367 and 4.4-12332 both accept that the cs is dropped into the image. Then sending #disableProgrammerFacilities disables the command keys, the World menu and the halos. In the right click World menu the entries to enable the Flaps and the main docking bar are not removed and give access to the tools. The docking bar is not disabled automatically. http://wiki.squeak.org/squeak/518 still has that cs. So I'd say the method in Preferences should either be removed or the comment updated accordingly. No idea if the remaining accesses to the tools should be disabled in the cs or in the method in Preferences. Cheers, Herbert From dnorton at mindspring.com Mon May 4 15:25:00 2015 From: dnorton at mindspring.com (Dan Norton) Date: Mon May 4 15:25:06 2015 Subject: [squeak-dev] Re: disableProgrammerFacilities In-Reply-To: <1430717211830-4824141.post@n4.nabble.com> References: <5546AEEA.19015.190244A@dnorton.mindspring.com>, <1430717211830-4824141.post@n4.nabble.com> Message-ID: <55478F4C.10016.3E20AA@dnorton.mindspring.com> On 3 May 2015 at 22:26, Marcel Taeumel wrote: > Interesting. :) Can elaborate on what it means to "disable the IDE" > in terms > of Squeak? > > - System Browser, Inspctor, Explorer, Message Set, ... > - Morphic Halos, Meta menus > - Distinct keyboard shortcuts such as CMD+P, CMD+D, ... > - Shrinking down the world menu to Transcript/Save/Quit > - ... That's a good list. I would like there to be no way for a user to get to any part of the IDE. Also not be able to determine the programming language. > > Is it a deployment scenario? What might happen if a debugger wants > to pop > up? > Definitely only for deployment of a robust application IMO. The comments and pop-ups in #disableProgrammerFacilities provide caveats. > ...What does eToys do? =) > Good question. - Dan From commits at source.squeak.org Mon May 4 15:41:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 15:41:19 2015 Subject: [squeak-dev] The Trunk: System-topa.734.mcz Message-ID: Tobias Pape uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-topa.734.mcz ==================== Summary ==================== Name: System-topa.734 Author: topa Time: 4 May 2015, 5:40:46.351 pm UUID: 1de527ef-9ee8-4973-aee5-6b456e5031d1 Ancestors: System-topa.733 (typo) =============== Diff against System-topa.733 =============== Item was changed: ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- keepTrackOfObjectHistory + ^ ObjectHistoryEnabled ifNil: [ Current ifNil: [false] ifNotNil: [:objectHistory | objectHistory isRunning]]! From marcel.taeumel at student.hpi.uni-potsdam.de Mon May 4 15:39:16 2015 From: marcel.taeumel at student.hpi.uni-potsdam.de (Marcel Taeumel) Date: Mon May 4 15:54:52 2015 Subject: [squeak-dev] Re: MorphicEvent >> timeStamp ??? In-Reply-To: References: <1430732773838-4824194.post@n4.nabble.com> Message-ID: <1430753956440-4824337.post@n4.nabble.com> http://forum.world.st/win32-Morphic-event-timeStamp-bug-tp4824244.html I found the bug in the windows vm. :) Best, Marcel -- View this message in context: http://forum.world.st/MorphicEvent-timeStamp-tp4824194p4824337.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Mon May 4 16:06:32 2015 From: karlramberg at gmail.com (karl ramberg) Date: Mon May 4 16:06:36 2015 Subject: [squeak-dev] Re: disableProgrammerFacilities In-Reply-To: <55478F4C.10016.3E20AA@dnorton.mindspring.com> References: <5546AEEA.19015.190244A@dnorton.mindspring.com> <1430717211830-4824141.post@n4.nabble.com> <55478F4C.10016.3E20AA@dnorton.mindspring.com> Message-ID: On Mon, May 4, 2015 at 5:25 PM, Dan Norton wrote: > On 3 May 2015 at 22:26, Marcel Taeumel wrote: > > > Interesting. :) Can elaborate on what it means to "disable the IDE" > > in terms > > of Squeak? > > > > - System Browser, Inspctor, Explorer, Message Set, ... > > - Morphic Halos, Meta menus > > - Distinct keyboard shortcuts such as CMD+P, CMD+D, ... > > - Shrinking down the world menu to Transcript/Save/Quit > > - ... > > That's a good list. I would like there to be no way for a user to get to > any part of the IDE. Also > not be able to determine the programming language. > > > > Is it a deployment scenario? What might happen if a debugger wants > > to pop > > up? > > > > Definitely only for deployment of a robust application IMO. The comments > and pop-ups in > #disableProgrammerFacilities provide caveats. > > > ...What does eToys do? =) > > > > Good question. > Etoys set the etoyFriendly preference to true. That disables the world menu and make debugger just signal an error instead of the full debugger. EtoyFriendly is not used to totally disable the whole system, more to keep kids on the topic of Etoys. The whole Squeak environment is too much for most elementary school classes. You can bypass etoysFriendly quite easily. Browse senders of etoysFriendly to see how it is used. Karl -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/d6b1a80c/attachment.htm From commits at source.squeak.org Mon May 4 17:47:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:47:05 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.623.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.623.mcz ==================== Summary ==================== Name: Collections.spur-tfel.623 Author: eem Time: 4 May 2015, 10:45:07.76 am UUID: b7da6afc-b6c4-434f-9016-42323d5510b5 Ancestors: Collections-tfel.623, Collections.spur-nice.622 Collections-tfel.623 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 =============== Diff against Collections-tfel.623 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:47:02.563 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:47:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:47:15 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.624.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.624.mcz ==================== Summary ==================== Name: Collections.spur-tfel.624 Author: eem Time: 4 May 2015, 10:45:10.022 am UUID: 58d939e7-2053-4557-9d02-2915caa5f8d2 Ancestors: Collections-tfel.624, Collections.spur-tfel.623 Collections-tfel.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String =============== Diff against Collections-tfel.624 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:47:11.72 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:47:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:47:49 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.622.mcz ==================== Summary ==================== Name: Collections.spur-nice.622 Author: eem Time: 4 May 2015, 10:45:05.244 am UUID: 02450614-82e9-4d33-95fd-3fede06790d2 Ancestors: Collections-nice.622, Collections.spur-mt.621 Collections-nice.622 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 #toBraceStack: is not used for compiling { } for so long that it's really time to get rid of it. Symbol>>numArgs: does not need to copy self into a temp var. =============== Diff against Collections-nice.622 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:47:40.493 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: 'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: 'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: 'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:47:56 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:47:57 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.625.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.625.mcz ==================== Summary ==================== Name: Collections.spur-mt.625 Author: eem Time: 4 May 2015, 10:44:51.265 am UUID: dfec67f7-30e1-48a9-8ec3-57b3a7518845 Ancestors: Collections-mt.625 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Speed-up #endsWith: for strings. =============== Diff against Collections-mt.625 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:47:48.713 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:48:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:48:29 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.626.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.626.mcz ==================== Summary ==================== Name: Collections.spur-mt.626 Author: eem Time: 4 May 2015, 10:44:53.357 am UUID: 8023bfd7-d8f7-40de-a7e2-4e70a96eee6c Ancestors: Collections-mt.626, Collections.spur-mt.625 Collections-mt.626 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. =============== Diff against Collections-mt.626 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:48:25.726 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:48:56 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:48:58 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.627.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.627.mcz ==================== Summary ==================== Name: Collections.spur-ul.627 Author: eem Time: 4 May 2015, 10:45:12.362 am UUID: b2f54288-1639-463b-9a3a-c94bad8c3d00 Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. =============== Diff against Collections-ul.627 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:48:56.118 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:49:16 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:49:17 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.628.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.628.mcz ==================== Summary ==================== Name: Collections.spur-ul.628 Author: eem Time: 4 May 2015, 10:45:14.954 am UUID: 92bfce50-a0d8-485c-861a-069499b59012 Ancestors: Collections-ul.628, Collections.spur-ul.627 Collections-ul.628 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.625. =============== Diff against Collections-ul.628 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:49:15.03 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:50:01 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:50:02 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.629.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.629.mcz ==================== Summary ==================== Name: Collections.spur-mt.629 Author: eem Time: 4 May 2015, 10:44:55.14 am UUID: 92f4f91d-7934-4709-8da9-3a34926c9a85 Ancestors: Collections-mt.629 Collections-mt.629 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... =============== Diff against Collections-mt.629 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:49:50.743 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:50:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:50:08 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.630.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.630.mcz ==================== Summary ==================== Name: Collections.spur-mt.630 Author: eem Time: 4 May 2015, 10:44:57.555 am UUID: a058abc7-410c-4c88-a852-8dbbab42cfcd Ancestors: Collections-mt.630, Collections.spur-mt.629 Collections-mt.630 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HTML escaping added to html read/writer =============== Diff against Collections-mt.630 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:49:56.683 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:50:19 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:50:22 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.631.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.631.mcz ==================== Summary ==================== Name: Collections.spur-mt.631 Author: eem Time: 4 May 2015, 10:44:59.659 am UUID: a6adc914-e00e-4848-9403-afd33ace00fb Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HtmlReadWriter: support for comments added, list of ignored tags added =============== Diff against Collections-mt.631 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 5:50:01.082 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 17:52:51 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:52:53 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.728.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.728.mcz ==================== Summary ==================== Name: System.spur-cmm.728 Author: eem Time: 4 May 2015, 10:45:35.676 am UUID: f6c1e329-85d6-4eec-8229-db3ad1f5bfbb Ancestors: System-cmm.728 System-cmm.728 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Restored the much safer version of Preferences class>>#preferenceAt:ifAbsent:. =============== Diff against System-cmm.728 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 4 17:53:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:53:30 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.729.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.729.mcz ==================== Summary ==================== Name: System.spur-kfr.729 Author: eem Time: 4 May 2015, 10:45:39.836 am UUID: edc655f4-a1f2-429c-904f-28621faa5e74 Ancestors: System-kfr.729, System.spur-cmm.728 System-kfr.729 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Add a 'refresh this menu' item to the Standard System Fonts menu, so it can update to reflect the current selected fonts =============== Diff against System-kfr.729 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 4 17:54:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:54:45 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.730.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.730.mcz ==================== Summary ==================== Name: System.spur-kfr.730 Author: eem Time: 4 May 2015, 10:45:44.083 am UUID: fc993ec0-a6f6-48cd-8008-f38b0d33cd33 Ancestors: System-kfr.730, System.spur-kfr.729 System-kfr.730 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Make sure the menu icons are added if needed to Standard System Fonts menu =============== Diff against System-kfr.730 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 4 17:54:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:54:57 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.731.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.731.mcz ==================== Summary ==================== Name: System.spur-nice.731 Author: eem Time: 4 May 2015, 10:45:48.579 am UUID: 84394759-26f8-4fe8-ad15-cd406fd24de6 Ancestors: System-nice.731, System.spur-kfr.730 System-nice.731 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 A DummyStream may do nothing, but shall mimic the answer of a regular stream. =============== Diff against System-nice.731 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 4 17:55:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:55:19 2015 Subject: [squeak-dev] The Inbox: HelpSystem-Core-kfr.74.mcz Message-ID: A new version of HelpSystem-Core was added to project The Inbox: http://source.squeak.org/inbox/HelpSystem-Core-kfr.74.mcz ==================== Summary ==================== Name: HelpSystem-Core-kfr.74 Author: kfr Time: 4 May 2015, 7:54:59.518 pm UUID: 0661be6b-4789-064c-badd-75797c7e030c Ancestors: HelpSystem-Core-mt.73 Make all HelpTopics have a "title" page that can give a description for what the HelpTopic is about. Add this description in 'contents' method =============== Diff against HelpSystem-Core-mt.73 =============== Item was changed: ----- Method: ClassBasedHelpTopic>>contents (in category 'accessing') ----- contents + "Title page for the book" + ^helpClass contents contents + ! - "A book has no contents. Only its pages do." - - ^ ''! Item was added: + ----- Method: CustomHelp class>>contents (in category 'accessing') ----- + contents + + ^''! From commits at source.squeak.org Mon May 4 17:55:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:55:53 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.733.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.733.mcz ==================== Summary ==================== Name: System.spur-topa.733 Author: eem Time: 4 May 2015, 10:45:59.019 am UUID: d1f51581-f0cb-4f8b-8262-9f8609d7c0aa Ancestors: System-topa.733, System.spur-nice.732 System-topa.733 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Make a preference to dis/enable the Object History. =============== Diff against System-topa.733 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 4 17:56:25 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 17:56:28 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.734.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.734.mcz ==================== Summary ==================== Name: System.spur-topa.734 Author: eem Time: 4 May 2015, 10:46:03.456 am UUID: 25217eaf-056d-4cee-9179-25ff5cfd532f Ancestors: System-topa.734, System.spur-topa.733 System-topa.734 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 (typo) =============== Diff against System-topa.734 =============== Item was removed: - ----- Method: Object>>oopAge (in category '*system-support') ----- - oopAge - ^ ObjectHistory current ageOf: self! Item was removed: - ----- Method: Object>>oopTimestamp (in category '*system-support') ----- - oopTimestamp - ^ ObjectHistory current timestampOf: self! Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From asqueaker at gmail.com Mon May 4 18:00:57 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 18:00:59 2015 Subject: [squeak-dev] Re: Changing button groups/order in browsers In-Reply-To: References: <1430659768347-4823991.post@n4.nabble.com> <1430743283559-4824268.post@n4.nabble.com> Message-ID: On Mon, May 4, 2015 at 9:28 AM, karl ramberg wrote: > I was wondering about the senders and implementors buttons. It would be nice > to be able to chose either local or global scope. I'm not sure we have a > nice button widget that can do that. Currently those buttons open a list of implementors with one click but which can be subsequently filtered via "filter message list..." | "messages that...". Then, in the dialog, simply enter the expression how you want to filter. From eliot.miranda at gmail.com Mon May 4 18:13:31 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon May 4 18:13:36 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: This breaks my image, dumping it into the emergency evaluator, I *think* because the new LetterMask, AlphaNumbericMask and DigitBit variables are not handledf correctly by the Spur bootstrap. Sigh. So for those of you using Spur please *don't* update until I've fixed the bootstrap. You know, by /not/ releasing, we are delaying because now I am fixing the bootstrap to keep up with development, instead of us having released, and being able to freely commit on Spur. We are now wasting cycles. At least I am. On Mon, May 4, 2015 at 10:46 AM, wrote: > Eliot Miranda uploaded a new version of Collections to project The Trunk: > http://source.squeak.org/trunk/Collections.spur-nice.622.mcz > > ==================== Summary ==================== > > Name: Collections.spur-nice.622 > Author: eem > Time: 4 May 2015, 10:45:05.244 am > UUID: 02450614-82e9-4d33-95fd-3fede06790d2 > Ancestors: Collections-nice.622, Collections.spur-mt.621 > > Collections-nice.622 patched for Spur by > SpurBootstrapMonticelloPackagePatcher Cog-eem.262 > > #toBraceStack: is not used for compiling { } for so long that it's really > time to get rid of it. > > Symbol>>numArgs: does not need to copy self into a temp var. > > =============== Diff against Collections-nice.622 =============== > > Item was changed: > ----- Method: Array>>elementsExchangeIdentityWith: (in category > 'converting') ----- > elementsExchangeIdentityWith: otherArray > + "This primitive performs a bulk mutation, causing all pointers to > the elements of the > + receiver to be replaced by pointers to the corresponding elements > of otherArray. > + At the same time, all pointers to the elements of otherArray are > replaced by > + pointers to the corresponding elements of this array. The > identityHashes remain > + with the pointers rather than with the objects so that objects in > hashed structures > + should still be properly indexed after the mutation." > - "This primitive performs a bulk mutation, causing all pointers to > the elements of this array to be replaced by pointers to the corresponding > elements of otherArray. At the same time, all pointers to the elements of > otherArray are replaced by pointers to the corresponding elements of this > array. The identityHashes remain with the pointers rather than with the > objects so that objects in hashed structures should still be properly > indexed after the mutation." > > + > + ec == #'bad receiver' ifTrue: > + [^self error: 'receiver must be of class Array']. > + ec == #'bad argument' ifTrue: > + [^self error: (otherArray class == Array > + ifTrue: ['arg must be of > class Array'] > + ifFalse: ['receiver and > argument must have the same size'])]. > + ec == #'inappropriate operation' ifTrue: > + [^self error: 'can''t become immediates such as > SmallIntegers or Characters']. > + ec == #'no modification' ifTrue: > + [^self error: 'can''t become immutable objects']. > + ec == #'object is pinned' ifTrue: > + [^self error: 'can''t become pinned objects']. > + ec == #'insufficient object memory' ifTrue: > + [Smalltalk garbageCollect < 1048576 ifTrue: > + [Smalltalk growMemoryByAtLeast: 1048576]. > + ^self elementsExchangeIdentityWith: otherArray]. > + self primitiveFailed! > - > - otherArray class == Array ifFalse: [^ self error: 'arg must be > array']. > - self size = otherArray size ifFalse: [^ self error: 'arrays must > be same size']. > - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ > self error: 'can''t become SmallIntegers']. > - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) > ifTrue: [^ self error: 'can''t become SmallIntegers']. > - self with: otherArray do:[:a :b| a == b ifTrue:[^self > error:'can''t become yourself']]. > - > - "Must have failed because not enough space in forwarding table > (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC > and try again only once" > - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect > - ifTrue: [^ self primitiveFailed]. > - ^ self elementsExchangeIdentityWith: otherArray! > > Item was changed: > ----- Method: Array>>elementsForwardIdentityTo: (in category > 'converting') ----- > elementsForwardIdentityTo: otherArray > + "This primitive performs a bulk mutation, causing all pointers to > the elements of the > + receiver to be replaced by pointers to the corresponding elements > of otherArray. > + The identityHashes remain with the pointers rather than with the > objects so that > + the objects in this array should still be properly indexed in any > existing hashed > + structures after the mutation." > + > - "This primitive performs a bulk mutation, causing all pointers to > the elements of this array to be replaced by pointers to the corresponding > elements of otherArray. The identityHashes remain with the pointers rather > than with the objects so that the objects in this array should still be > properly indexed in any existing hashed structures after the mutation." > - > self primitiveFailed! > > Item was changed: > ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category > 'converting') ----- > elementsForwardIdentityTo: otherArray copyHash: copyHash > + "This primitive performs a bulk mutation, causing all pointers to > the elements of the > + receiver to be replaced by pointers to the corresponding elements > of otherArray. > + If copyHash is true, the identityHashes remain with the pointers > rather than with the > + objects so that the objects in the receiver should still be > properly indexed in any > + existing hashed structures after the mutation. If copyHash is > false, then the hashes > + of the objects in otherArray remain unchanged. If you know what > you're doing this > + may indeed be what you want." > + > - "This primitive performs a bulk mutation, causing all pointers to > the elements of this array to be replaced by pointers to the corresponding > elements of otherArray. The identityHashes remain with the pointers rather > than with the objects so that the objects in this array should still be > properly indexed in any existing hashed structures after the mutation." > - > self primitiveFailed! > > Item was changed: > ==== ERROR === > > Error: Unrecognized class type > > 4 May 2015 5:47:40.493 pm > > VM: unix - a SmalltalkImage > Image: Squeak3.11alpha [latest update: #8824] > > SecurityManager state: > Restricted: false > FileAccess: true > SocketAccess: true > Working Dir /home/squeaksource > Trusted Dir /home/squeaksource/secure > Untrusted Dir /home/squeaksource/My Squeak > > MCClassDefinition(Object)>>error: > Receiver: a MCClassDefinition(Character) > Arguments and temporary variables: > aString: 'Unrecognized class type' > Receiver's instance variables: > name: #Character > superclassName: #Magnitude > variables: an OrderedCollection(a > MCClassVariableDefinition(CharacterTable) a M...etc... > category: 'Collections-Strings' > type: #immediate > comment: 'I represent a character by storing its > associated Unicode as an unsig...etc... > commentStamp: 'eem 8/12/2014 14:53' > traitComposition: nil > classTraitComposition: nil > > MCClassDefinition>>kindOfSubclass > Receiver: a MCClassDefinition(Character) > Arguments and temporary variables: > > Receiver's instance variables: > name: #Character > superclassName: #Magnitude > variables: an OrderedCollection(a > MCClassVariableDefinition(CharacterTable) a M...etc... > category: 'Collections-Strings' > type: #immediate > comment: 'I represent a character by storing its > associated Unicode as an unsig...etc... > commentStamp: 'eem 8/12/2014 14:53' > traitComposition: nil > classTraitComposition: nil > > MCClassDefinition>>printDefinitionOn: > Receiver: a MCClassDefinition(Character) > Arguments and temporary variables: > stream: a WriteStream > Receiver's instance variables: > name: #Character > superclassName: #Magnitude > variables: an OrderedCollection(a > MCClassVariableDefinition(CharacterTable) a M...etc... > category: 'Collections-Strings' > type: #immediate > comment: 'I represent a character by storing its > associated Unicode as an unsig...etc... > commentStamp: 'eem 8/12/2014 14:53' > traitComposition: nil > classTraitComposition: nil > > [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: > Receiver: a MCDiffyTextWriter > Arguments and temporary variables: > definition: a WriteStream > s: a MCClassDefinition(Character) > Receiver's instance variables: > stream: a WriteStream > initStream: nil > > > --- The full stack --- > MCClassDefinition(Object)>>error: > MCClassDefinition>>kindOfSubclass > MCClassDefinition>>printDefinitionOn: > [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > String class(SequenceableCollection class)>>new:streamContents: > String class(SequenceableCollection class)>>streamContents: > MCDiffyTextWriter(MCTextWriter)>>chunkContents: > MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: > MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: > MCClassDefinition>>accept: > [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: > String class(SequenceableCollection class)>>new:streamContents: > String class(SequenceableCollection class)>>streamContents: > MCDiffyTextWriter(MCTextWriter)>>visitInFork: > MCDiffyTextWriter>>writePatchFrom:to: > MCDiffyTextWriter>>writeModification: > [] in MCDiffyTextWriter>>writePatch: > SortedCollection(OrderedCollection)>>do: > MCDiffyTextWriter>>writePatch: > SSDiffyTextWriter>>writePatch: > [] in SSDiffyTextWriter>>writeVersion:for: > BlockClosure>>on:do: > SSDiffyTextWriter>>writeVersion:for: > [] in SSEMailSubscription>>versionAdded:to: > BlockClosure>>on:do: > SSEMailSubscription>>versionAdded:to: > [] in [] in SSProject>>versionAdded: > [] in BlockClosure>>newProcess > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/75b5f264/attachment-0001.htm From asqueaker at gmail.com Mon May 4 18:24:35 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 18:24:38 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Mon, May 4, 2015 at 1:13 PM, Eliot Miranda wrote: > This breaks my image, dumping it into the emergency evaluator, I *think* > because the new LetterMask, AlphaNumbericMask and DigitBit variables are not > handledf correctly by the Spur bootstrap. Sigh. So for those of you using > Spur please *don't* update until I've fixed the bootstrap. > > You know, by /not/ releasing, we are delaying because now I am fixing the > bootstrap to keep up with development, instead of us having released, and > being able to freely commit on Spur. We are now wasting cycles. At least I > am. I was having a similar thought just today because I needed an up-to-date Spur image and thought about asking whether you'd like someone to set that up as an automatic job, then realized, we just need to release. Which, we are. We are not "not releasing", we _are_ releasing, its just taking a bit longer than expected because there are still some bugs and loose ends (unrelated to Marcel's work) still needing tied up. Maintaining the separate branch and the bootstrap is a hassle, but it shouldn't be much longer. From commits at source.squeak.org Mon May 4 18:39:37 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 18:39:39 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.624.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.624.mcz ==================== Summary ==================== Name: Collections.spur-tfel.624 Author: eem Time: 4 May 2015, 11:39:07.236 am UUID: 19e2bbd6-ffa8-47a9-9984-7811ae6464b8 Ancestors: Collections-tfel.624, Collections.spur-tfel.623 Collections-tfel.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String =============== Diff against Collections-tfel.624 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 6:39:36.926 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 18:40:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 18:40:14 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.625.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.625.mcz ==================== Summary ==================== Name: Collections.spur-mt.625 Author: eem Time: 4 May 2015, 11:38:55.717 am UUID: b51e8df7-7539-48ec-98a1-5bc641278603 Ancestors: Collections-mt.625 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Speed-up #endsWith: for strings. =============== Diff against Collections-mt.625 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 6:40:06.122 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 18:40:23 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 18:40:26 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.627.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.627.mcz ==================== Summary ==================== Name: Collections.spur-ul.627 Author: eem Time: 4 May 2015, 11:39:08.955 am UUID: b6eeb6ab-6534-4315-9d6c-5dbc6eb2335a Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. =============== Diff against Collections-ul.627 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 6:40:11.448 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 18:40:47 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 18:40:48 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.631.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.631.mcz ==================== Summary ==================== Name: Collections.spur-mt.631 Author: eem Time: 4 May 2015, 11:39:02.231 am UUID: 44b9e1ad-bef0-4fcd-b664-830a91657679 Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HtmlReadWriter: support for comments added, list of ignored tags added =============== Diff against Collections-mt.631 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 6:40:46.756 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 19:11:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 19:11:42 2015 Subject: [squeak-dev] The Trunk: Collections-ul.624.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.624.mcz ==================== Summary ==================== Name: Collections-ul.624 Author: ul Time: 1 May 2015, 1:40:09.445 pm UUID: a89640e5-e0cc-44e1-9613-e065b78258ad Ancestors: Collections-tfel.623 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. =============== Diff against Collections-tfel.623 =============== Item was changed: Magnitude subclass: #Character instanceVariableNames: 'value' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + ClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + ClassificationTable at: code + 1 put: value ]! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + value < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | numArgs aStream offs |. - (numArgs := self numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From nicolas.cellier.aka.nice at gmail.com Mon May 4 19:14:53 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Mon May 4 19:14:55 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-05-04 20:24 GMT+02:00 Chris Muller : > On Mon, May 4, 2015 at 1:13 PM, Eliot Miranda > wrote: > > This breaks my image, dumping it into the emergency evaluator, I *think* > > because the new LetterMask, AlphaNumbericMask and DigitBit variables are > not > > handledf correctly by the Spur bootstrap. Sigh. So for those of you > using > > Spur please *don't* update until I've fixed the bootstrap. > > > I failed to sea why historical compilation of brace construct would cause such grief, but I understand now, these are the changes of Levente relative to Character classification... > > You know, by /not/ releasing, we are delaying because now I am fixing the > > bootstrap to keep up with development, instead of us having released, and > > being able to freely commit on Spur. We are now wasting cycles. At > least I > > am. > > I was having a similar thought just today because I needed an > up-to-date Spur image and thought about asking whether you'd like > someone to set that up as an automatic job, then realized, we just > need to release. > > Which, we are. We are not "not releasing", we _are_ releasing, its > just taking a bit longer than expected because there are still some > bugs and loose ends (unrelated to Marcel's work) still needing tied > up. Maintaining the separate branch and the bootstrap is a hassle, > but it shouldn't be much longer. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/3e890f0f/attachment.htm From nicolas.cellier.aka.nice at gmail.com Mon May 4 19:16:13 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Mon May 4 19:16:15 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: 2015-05-04 21:14 GMT+02:00 Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com>: > > > 2015-05-04 20:24 GMT+02:00 Chris Muller : > >> On Mon, May 4, 2015 at 1:13 PM, Eliot Miranda >> wrote: >> > This breaks my image, dumping it into the emergency evaluator, I *think* >> > because the new LetterMask, AlphaNumbericMask and DigitBit variables >> are not >> > handledf correctly by the Spur bootstrap. Sigh. So for those of you >> using >> > Spur please *don't* update until I've fixed the bootstrap. >> > >> > > I failed to sea why historical compilation of brace construct would cause > such grief, > hem, I see my English improving every day, but it's a long road... > but I understand now, these are the changes of Levente relative to > Character classification... > > > >> > You know, by /not/ releasing, we are delaying because now I am fixing >> the >> > bootstrap to keep up with development, instead of us having released, >> and >> > being able to freely commit on Spur. We are now wasting cycles. At >> least I >> > am. >> >> I was having a similar thought just today because I needed an >> up-to-date Spur image and thought about asking whether you'd like >> someone to set that up as an automatic job, then realized, we just >> need to release. >> >> Which, we are. We are not "not releasing", we _are_ releasing, its >> just taking a bit longer than expected because there are still some >> bugs and loose ends (unrelated to Marcel's work) still needing tied >> up. Maintaining the separate branch and the bootstrap is a hassle, >> but it shouldn't be much longer. >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/cc890296/attachment.htm From commits at source.squeak.org Mon May 4 19:28:51 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 19:28:53 2015 Subject: [squeak-dev] The Trunk: Collections-ul.624.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.624.mcz ==================== Summary ==================== Name: Collections-ul.624 Author: ul Time: 1 May 2015, 1:40:09.445 pm UUID: a89640e5-e0cc-44e1-9613-e065b78258ad Ancestors: Collections-tfel.623 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. =============== Diff against Collections-tfel.623 =============== Item was changed: Magnitude subclass: #Character instanceVariableNames: 'value' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + ClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + ClassificationTable at: code + 1 put: value ]! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + value < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | numArgs aStream offs |. - (numArgs := self numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Mon May 4 19:30:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 19:30:51 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.624.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.624.mcz ==================== Summary ==================== Name: Collections.spur-ul.624 Author: eem Time: 4 May 2015, 12:30:12.646 pm UUID: c1b148d5-799b-4499-b0c5-e99097c07e75 Ancestors: Collections-ul.624, Collections.spur-tfel.623 Collections-ul.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. =============== Diff against Collections-ul.624 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 7:30:49.411 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 19:31:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 19:31:14 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.625.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.625.mcz ==================== Summary ==================== Name: Collections.spur-mt.625 Author: eem Time: 4 May 2015, 12:29:58.935 pm UUID: bb38abbd-cd4e-4424-a8bc-bce4fcd57cf2 Ancestors: Collections-mt.625, Collections.spur-tfel.624 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Speed-up #endsWith: for strings. =============== Diff against Collections-mt.625 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 7:31:11.642 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 19:31:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 19:31:41 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.626.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.626.mcz ==================== Summary ==================== Name: Collections.spur-mt.626 Author: eem Time: 4 May 2015, 12:30:01.067 pm UUID: 031bcaf5-36b0-4b75-a928-36b6582a7049 Ancestors: Collections-mt.626, Collections.spur-mt.625 Collections-mt.626 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. =============== Diff against Collections-mt.626 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 7:31:38.19 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 19:31:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 19:31:44 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.628.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.628.mcz ==================== Summary ==================== Name: Collections.spur-ul.628 Author: eem Time: 4 May 2015, 12:30:17.631 pm UUID: ba0bdead-ea60-4a19-9eee-109681404912 Ancestors: Collections-ul.628, Collections.spur-ul.627 Collections-ul.628 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.625. =============== Diff against Collections-ul.628 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 7:31:38.737 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 4 20:12:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 20:12:40 2015 Subject: [squeak-dev] The Inbox: MonticelloConfigurations-dtl.131.mcz Message-ID: David T. Lewis uploaded a new version of MonticelloConfigurations to project The Inbox: http://source.squeak.org/inbox/MonticelloConfigurations-dtl.131.mcz ==================== Summary ==================== Name: MonticelloConfigurations-dtl.131 Author: dtl Time: 4 May 2015, 4:12:33.318 pm UUID: 2e9a311b-a484-4f84-af4e-96dd6d373bfe Ancestors: MonticelloConfigurations-mt.130 Let MCMcmUpdater be instance based. The default system updater is MCMcmUpdater default. Updaters are associated with repositories ('http://source.squeak.org/trunk'), and are kept in a registry (MCMcmUpdater updaters) keyed by repository URL. Each updater has its own updateMapName (such as 'update' or 'update.spur') and maintains its own lastUpdateMap. System preferences apply to the default updater. A SqueakMap package head stream can specify its update map name independent of the Squeak trunk update stream preference, for example: "MCMcmUpdater updateMapName: 'update.oscog' repository: 'http://source.squeak.org/VMMaker' =============== Diff against MonticelloConfigurations-mt.130 =============== Item was changed: Object subclass: #MCMcmUpdater + instanceVariableNames: 'updateMapName lastUpdateMap' + classVariableNames: 'DefaultUpdateURL LastUpdateMap SkipPackages UpdateFromServerAtStartup UpdateMapName UpdateMissingPackages Updaters' - instanceVariableNames: '' - classVariableNames: 'DefaultUpdateURL LastUpdateMap SkipPackages UpdateFromServerAtStartup UpdateMapName UpdateMissingPackages' poolDictionaries: '' category: 'MonticelloConfigurations'! + !MCMcmUpdater commentStamp: 'dtl 5/4/2015 16:03' prior: 0! - !MCMcmUpdater commentStamp: 'cbc 8/26/2010 16:42' prior: 0! MCMcmUpdater provides utility methods for updating Monticello packages from Monticello configurations. When Monticello configurations are stored in a repository (or repositories), MCMcmUpdater acts as an update stream. It first ensures that each configuration map has been loaded in sequence, then updates the last configuration map to the most recent version for each specified package, and finally loads these versions to produce a fully updated configuration. Currently if a set of packages are unloaded from the image, using this class to reload them may cause problems, depending on what dependencies those classes have. Success is not assured. Removing packages via SmalltalkImage>>unloadAllKnownPackages will be successful, it flags the packages removed so that they are not loaded by this utility. If you wish to not have MCMcmUpdater update packages, there are two ways to handle this: 1) To have MCMcmUpdater not update any packages not currently in the image set the UpdateMissingPackages preference to false: MCMcmUpdater updateMissingPackages: false Note that any new packages added to the repositories will not be picked up when this is turned off. 2) To have MCMcmUpdater not update a specific package, evaluate MCMcmUpdater disableUpdatesOfPackage: Class Variables definitions: DefaultUpdateURL - String: the URL that will be checked by default for updates. This would be set for a common standard location to check. + Updaters - A dictionary of MCMcmUpdater instances keyed by repository URL. - LastUpdateMap - Dictionary of Integer: version number of the last loaded update map per repository. Keeps track of the last configuration map, so that the utility will not have to run through the full history in the repositories each time you ask to update. SkipPackages - Set of Strings: names of packages to not update in MCMcmUpdater (empty by default). UpdateMissingPackages - Boolean: if true (default), new packages in the update config map will be loaded unless they are in SkipPackages. If false, packages not currently loaded in the image will not be loaded by MCMcmUpdater. (This can be dangerous if packages are split - use at your own risk). + + Instance Variables: + + updateMapName - Base name of the files used for this updater, typically a name such as 'update' or 'update.spur'. + + lastUpdateMap - Dictionary of Integer: version number of the last loaded update map per repository. Keeps track of the last configuration map, so that the utility will not have to run through the full history in the repositories each time you ask to update. ! Item was added: + ----- Method: MCMcmUpdater class>>default (in category 'instance creation') ----- + default + "The default instance for system updates. Uses a default update map + name that may be set as a preference to enable a specific update stream + for a repository." + + ^ self updaters + at: self defaultUpdateURL + ifAbsentPut: [self updateMapName: self updateMapName]! Item was changed: ----- Method: MCMcmUpdater class>>initialize (in category 'class initialization') ----- initialize "MCMcmUpdater initialize" LastUpdateMap ifNil:[ LastUpdateMap := Dictionary new. ]. DefaultUpdateURL ifNil:[ DefaultUpdateURL := MCHttpRepository trunkUrlString. + ]. + Updaters := nil. + self flag: #FIXME. + "The next line is to faciliate updating from class-side methods to instance based. + Building a new default update map is very time consuming, so do not do it. + Delete this after the transition is complete. Also delete class var LastUpdateMap + and its initialization above. -dtl May 2015" + LastUpdateMap ifNotNil: [ self default lastUpdateMap: LastUpdateMap ] + ! - ].! Item was removed: - ----- Method: MCMcmUpdater class>>refreshUpdateMapFor:with: (in category 'updating') ----- - refreshUpdateMapFor: r with: updateList - "Update the LastUpdateMap and answer a possibly reduced updateList" - - | config | - (LastUpdateMap at: r description ifAbsent: [0]) = 0 ifTrue: [ - "No update has ever been loaded from this repo. If no package is - present in the image either, we can skip right to the latest config" - config := r versionNamed: updateList last value. - (config dependencies anySatisfy: [:dep| dep package hasWorkingCopy]) - ifFalse: [ (self useLatestPackagesFrom: r) - ifTrue: [LastUpdateMap at: r description put: updateList last key. - ^ #()] - ifFalse: [ ^ updateList last: 1]]]. - ^ updateList - ! Item was changed: + ----- Method: MCMcmUpdater class>>skipPackages (in category 'preferences') ----- - ----- Method: MCMcmUpdater class>>skipPackages (in category 'private') ----- skipPackages ^SkipPackages ifNil: [SkipPackages := Set new]! Item was removed: - ----- Method: MCMcmUpdater class>>updateFromConfig: (in category 'updating') ----- - updateFromConfig: config - - "Skip packages that were specifically unloaded" - config dependencies: (config dependencies - reject: [:dep| self skipPackages includes: dep package name]). - self updateMissingPackages ifFalse:[ - "Skip packages that are not in the image" - config dependencies: (config dependencies - select: [:dep| dep package hasWorkingCopy])]. - (config dependencies allSatisfy:[:dep| dep isFulfilled]) - ifFalse:[config upgrade]. - ! Item was removed: - ----- Method: MCMcmUpdater class>>updateFromDefaultRepository (in category 'updating') ----- - updateFromDefaultRepository - "Update from the default repository only" - ^self updateFromRepositories: {self defaultUpdateURL}! Item was changed: ----- Method: MCMcmUpdater class>>updateFromRepositories: (in category 'updating') ----- updateFromRepositories: repositoryUrls "MCMcmUpdater updateFromRepositories: #( 'http://squeaksource.com/MCUpdateTest' )" + ^ self default updateFromRepositories: repositoryUrls! - | repos config | - MCConfiguration upgradeIsMerge: true. - LastUpdateMap ifNil:[LastUpdateMap := Dictionary new]. - "The list of repositories to consult in order" - repos := repositoryUrls collect:[:url| - MCRepositoryGroup default repositories - detect:[:r| r description = url] - ifNone:[ | r | - r := MCHttpRepository location: url user: '' password: ''. - MCRepositoryGroup default addRepository: r. - r]]. - - "The list of updates-author.version.mcm sorted by version" - repos do:[ :r | config := self updateFromRepository: r ]. - ^config! Item was added: + ----- Method: MCMcmUpdater class>>updateFromRepositories:using:baseName: (in category 'updating') ----- + updateFromRepositories: repositoryUrls using: updaterUrlKey baseName: baseName + "Update all repositoryUrls using an MCMcmUpdater identified by updaterUrlKey, and + using update map baseName" + + ^ (self updateMapName: baseName repository: updaterUrlKey) + updateFromRepositories: repositoryUrls! Item was removed: - ----- Method: MCMcmUpdater class>>updateFromRepository: (in category 'updating') ----- - updateFromRepository: repository - - | config | - repository cacheAllFileNamesDuring: [ | updateList | - updateList := self updateListFor: repository. - "Proceed only if there are updates available at all." - updateList ifNotEmpty: [ - updateList := self refreshUpdateMapFor: repository with: updateList. - "Now process each update file. Check if we have all dependencies and if not, - load the entire configuration (this is mostly to skip older updates quickly)" - updateList do:[:assoc| - ProgressNotification signal: '' extra: 'Processing ', assoc value. - config := repository versionNamed: assoc value. - self updateFromConfig: config. - LastUpdateMap at: repository description put: assoc key. - ] displayingProgress: 'Processing configurations'. - "We've loaded all the provided update configurations. - Use the latest configuration to update all the remaining packages." - (self useLatestPackagesFrom: repository) ifTrue: [ - config updateFromRepositories. - config upgrade]. - ]]. - ^ config - ! Item was changed: ----- Method: MCMcmUpdater class>>updateFromServer (in category 'updating') ----- updateFromServer "Update the image by loading all pending updates from the server." + + ^self default updateFromServer + ! - | config | - "Flush all caches. If a previous download failed this is often helpful" - MCFileBasedRepository flushAllCaches. - config := MCMcmUpdater updateFromDefaultRepository. - config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. - config setSystemVersion. - self inform: ('Update completed. - Current update number: ' translated, SystemVersion current highestUpdate).! Item was removed: - ----- Method: MCMcmUpdater class>>updateListFor: (in category 'private') ----- - updateListFor: repo - - | updateList allNames minVersion | - updateList := OrderedCollection new. - minVersion := LastUpdateMap at: repo description ifAbsent: [0]. - "Find all the update-*.mcm files" - allNames := 'Checking ', repo description - displayProgressFrom: 0 to: 1 during: [:bar| - bar value: 0. - repo allFileNamesOrCache ]. - allNames do: [:fileName | | version | - ((fileName endsWith: '.mcm') - and: [fileName packageAndBranchName = self updateMapName - and: [(version := fileName versionNumber) >= minVersion]]) - ifTrue: [updateList add: version -> fileName]]. - ^updateList sort! Item was changed: + ----- Method: MCMcmUpdater class>>updateMapName: (in category 'instance creation') ----- + updateMapName: baseName + "Answer a new instance with a base update name baseName such as + 'update' or 'update.oscog' " + + ^ self new updateMapName: baseName! - ----- Method: MCMcmUpdater class>>updateMapName: (in category 'preferences') ----- - updateMapName: aString - "Name for update map, without version info" - UpdateMapName := aString! Item was added: + ----- Method: MCMcmUpdater class>>updateMapName:repository: (in category 'instance creation') ----- + updateMapName: baseName repository: url + "Answer an instance for the given repository URL with a base update name + baseName. The instance will be updated in the Updaters dictionary if baseName + has changed." + + | updater | + updater := self updaters at: url ifAbsentPut: [ self updateMapName: baseName ]. + updater updateMapName = baseName + ifFalse: [ ^ self updaters at: url put: (self updateMapName: baseName )]. + ^ updater + ! Item was added: + ----- Method: MCMcmUpdater class>>updateUsing:baseName: (in category 'updating') ----- + updateUsing: updaterUrlKey baseName: baseName + "Update using an MCMcmUpdater identified by updaterUrlKey, and using + update map baseName" + + ^ (self updateMapName: baseName repository: updaterUrlKey) updateFromServer + ! Item was added: + ----- Method: MCMcmUpdater class>>updaters (in category 'accessing') ----- + updaters + "A dictionary of updaters, including the system default, indexed by repository URL" + + ^ Updaters ifNil: [ Updaters := Dictionary new ]! Item was removed: - ----- Method: MCMcmUpdater class>>useLatestPackagesFrom: (in category 'private') ----- - useLatestPackagesFrom: repo - "for overriding on a per repository basis" - ^true! Item was added: + ----- Method: MCMcmUpdater>>lastUpdateMap (in category 'accessing') ----- + lastUpdateMap + + ^ lastUpdateMap ifNil: [ lastUpdateMap := Dictionary new ] + ! Item was added: + ----- Method: MCMcmUpdater>>lastUpdateMap: (in category 'accessing') ----- + lastUpdateMap: aDictionary + + lastUpdateMap := aDictionary + ! Item was added: + ----- Method: MCMcmUpdater>>refreshUpdateMapFor:with: (in category 'updating') ----- + refreshUpdateMapFor: r with: updateList + "Update the lastUpdateMap and answer a possibly reduced updateList" + + | config | + (lastUpdateMap at: r description ifAbsent: [0]) = 0 ifTrue: [ + "No update has ever been loaded from this repo. If no package is + present in the image either, we can skip right to the latest config" + config := r versionNamed: updateList last value. + (config dependencies anySatisfy: [:dep| dep package hasWorkingCopy]) + ifFalse: [ (self useLatestPackagesFrom: r) + ifTrue: [lastUpdateMap at: r description put: updateList last key. + ^ #()] + ifFalse: [ ^ updateList last: 1]]]. + ^ updateList + ! Item was added: + ----- Method: MCMcmUpdater>>skipPackages (in category 'private') ----- + skipPackages + ^SkipPackages ifNil: [SkipPackages := Set new]! Item was added: + ----- Method: MCMcmUpdater>>updateFromConfig: (in category 'updating') ----- + updateFromConfig: config + + "Skip packages that were specifically unloaded" + config dependencies: (config dependencies + reject: [:dep| self class skipPackages includes: dep package name]). + self class updateMissingPackages ifFalse:[ + "Skip packages that are not in the image" + config dependencies: (config dependencies + select: [:dep| dep package hasWorkingCopy])]. + (config dependencies allSatisfy:[:dep| dep isFulfilled]) + ifFalse:[config upgrade]. + ! Item was added: + ----- Method: MCMcmUpdater>>updateFromDefaultRepository (in category 'updating') ----- + updateFromDefaultRepository + "Update from the default repository only" + ^self updateFromRepositories: {self class defaultUpdateURL}! Item was added: + ----- Method: MCMcmUpdater>>updateFromRepositories: (in category 'updating') ----- + updateFromRepositories: repositoryUrls + "MCMcmUpdater updateFromRepositories: #( + 'http://squeaksource.com/MCUpdateTest' + )" + + | repos config | + MCConfiguration upgradeIsMerge: true. + "The list of repositories to consult in order" + repos := repositoryUrls collect:[:url| + MCRepositoryGroup default repositories + detect:[:r| r description = url] + ifNone:[ | r | + r := MCHttpRepository location: url user: '' password: ''. + MCRepositoryGroup default addRepository: r. + r]]. + + "The list of updates-author.version.mcm sorted by version" + repos do:[ :r | config := self updateFromRepository: r ]. + ^config! Item was added: + ----- Method: MCMcmUpdater>>updateFromRepository: (in category 'updating') ----- + updateFromRepository: repository + + | config | + repository cacheAllFileNamesDuring: [ | updateList | + updateList := self updateListFor: repository. + "Proceed only if there are updates available at all." + updateList ifNotEmpty: [ + updateList := self refreshUpdateMapFor: repository with: updateList. + "Now process each update file. Check if we have all dependencies and if not, + load the entire configuration (this is mostly to skip older updates quickly)" + updateList do:[:assoc| + ProgressNotification signal: '' extra: 'Processing ', assoc value. + config := repository versionNamed: assoc value. + self updateFromConfig: config. + self lastUpdateMap at: repository description put: assoc key. + ] displayingProgress: 'Processing configurations'. + "We've loaded all the provided update configurations. + Use the latest configuration to update all the remaining packages." + (self useLatestPackagesFrom: repository) ifTrue: [ + config updateFromRepositories. + config upgrade]. + ]]. + ^ config + ! Item was added: + ----- Method: MCMcmUpdater>>updateFromServer (in category 'updating') ----- + updateFromServer + "Update the image by loading all pending updates from the server." + | config | + "Flush all caches. If a previous download failed this is often helpful" + MCFileBasedRepository flushAllCaches. + config := MCMcmUpdater default updateFromDefaultRepository. + config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. + config setSystemVersion. + self inform: ('Update completed. + Current update number: ' translated, SystemVersion current highestUpdate).! Item was added: + ----- Method: MCMcmUpdater>>updateListFor: (in category 'private') ----- + updateListFor: repo + + | updateList allNames minVersion | + updateList := OrderedCollection new. + minVersion := self lastUpdateMap at: repo description ifAbsent: [0]. + "Find all the update-*.mcm files" + allNames := 'Checking ', repo description + displayProgressFrom: 0 to: 1 during: [:bar| + bar value: 0. + repo allFileNamesOrCache ]. + allNames do: [:fileName | | version | + ((fileName endsWith: '.mcm') + and: [fileName packageAndBranchName = self updateMapName + and: [(version := fileName versionNumber) >= minVersion]]) + ifTrue: [updateList add: version -> fileName]]. + ^updateList sort! Item was added: + ----- Method: MCMcmUpdater>>updateMapName (in category 'accessing') ----- + updateMapName + "Name for update map, without version info" + + ^ updateMapName ifNil: [updateMapName := self class updateMapName]! Item was added: + ----- Method: MCMcmUpdater>>updateMapName: (in category 'accessing') ----- + updateMapName: aString + "Name for update map, without version info" + updateMapName := aString! Item was added: + ----- Method: MCMcmUpdater>>useLatestPackagesFrom: (in category 'private') ----- + useLatestPackagesFrom: repo + "for overriding on a per repository basis" + ^true! From commits at source.squeak.org Mon May 4 20:29:35 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 20:29:35 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.631.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.631.mcz ==================== Summary ==================== Name: Collections.spur-mt.631 Author: eem Time: 4 May 2015, 1:29:11.963 pm UUID: ef98a978-54a8-4f6b-ad3f-2474fb860bb1 Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HtmlReadWriter: support for comments added, list of ignored tags added =============== Diff against Collections-mt.631 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 8:29:34.813 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From leves at elte.hu Mon May 4 20:41:53 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon May 4 20:41:56 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Mon, 4 May 2015, Eliot Miranda wrote: > This breaks my image, dumping it into the emergency evaluator, I *think* because the new LetterMask, AlphaNumbericMask and DigitBit variables are not handledf correctly by the Spur bootstrap.? Sigh.? So for > those of you using Spur please *don't* update until I've fixed the bootstrap. > You know, by /not/ releasing, we are delaying because now I am fixing the bootstrap to keep up with development, instead of us having released, and being able to freely commit on Spur.? We are now wasting > cycles.? At least I am. Multilingual-ul.209 should be loaded before Collections-ul.627, and only then should Collections-ul.628 be loaded. In the regular Trunk, I added an update map which loads Multilingual-ul.209 and Collections-ul.627 first. (Multilingual was before Collections in the map, so the load order was already guaranteed). Levente > > On Mon, May 4, 2015 at 10:46 AM, wrote: > Eliot Miranda uploaded a new version of Collections to project The Trunk: > http://source.squeak.org/trunk/Collections.spur-nice.622.mcz > > ==================== Summary ==================== > > Name: Collections.spur-nice.622 > Author: eem > Time: 4 May 2015, 10:45:05.244 am > UUID: 02450614-82e9-4d33-95fd-3fede06790d2 > Ancestors: Collections-nice.622, Collections.spur-mt.621 > > Collections-nice.622 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 > > #toBraceStack: is not used for compiling { } for so long that it's really time to get rid of it. > > Symbol>>numArgs: does not need to copy self into a temp var. > > =============== Diff against Collections-nice.622 =============== > > Item was changed: > ? ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- > ? elementsExchangeIdentityWith: otherArray > +? ? ? ?"This primitive performs a bulk mutation, causing all pointers to the elements of the > +? ? ? ? receiver to be replaced by pointers to the corresponding elements of otherArray. > +? ? ? ? At the same time, all pointers to the elements of otherArray are replaced by > +? ? ? ? pointers to the corresponding elements of this array.? The identityHashes remain > +? ? ? ? with the pointers rather than with the objects so that objects in hashed structures > +? ? ? ? should still be properly indexed after the mutation." > -? ? ? ?"This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray.? At the same time, all > pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array.? The identityHashes remain with the pointers rather than with the objects so that > objects in hashed structures should still be properly indexed after the mutation." > > +? ? ? ? > +? ? ? ?ec == #'bad receiver' ifTrue: > +? ? ? ? ? ? ? ?[^self error: 'receiver must be of class Array']. > +? ? ? ?ec == #'bad argument' ifTrue: > +? ? ? ? ? ? ? ?[^self error: (otherArray class == Array > +? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ifTrue: ['arg must be of class Array'] > +? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ifFalse: ['receiver and argument must have the same size'])]. > +? ? ? ?ec == #'inappropriate operation' ifTrue: > +? ? ? ? ? ? ? ?[^self error: 'can''t become immediates such as SmallIntegers or Characters']. > +? ? ? ?ec == #'no modification' ifTrue: > +? ? ? ? ? ? ? ?[^self error: 'can''t become immutable objects']. > +? ? ? ?ec == #'object is pinned' ifTrue: > +? ? ? ? ? ? ? ?[^self error: 'can''t become pinned objects']. > +? ? ? ?ec == #'insufficient object memory' ifTrue: > +? ? ? ? ? ? ? ?[Smalltalk garbageCollect < 1048576 ifTrue: > +? ? ? ? ? ? ? ? ? ? ? ?[Smalltalk growMemoryByAtLeast: 1048576]. > +? ? ? ? ? ? ? ? ^self elementsExchangeIdentityWith: otherArray]. > +? ? ? ?self primitiveFailed! > -? ? ? ? > -? ? ? ?otherArray class == Array ifFalse: [^ self error: 'arg must be array']. > -? ? ? ?self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. > -? ? ? ?(self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. > -? ? ? ?(otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. > -? ? ? ?self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. > - > -? ? ? ?"Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:).? Do GC and try again only once" > -? ? ? ?(Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect > -? ? ? ? ? ? ? ?ifTrue: [^ self primitiveFailed]. > -? ? ? ?^ self elementsExchangeIdentityWith: otherArray! > > Item was changed: > ? ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- > ? elementsForwardIdentityTo: otherArray > +? ? ? ?"This primitive performs a bulk mutation, causing all pointers to the elements of the > +? ? ? ? receiver to be replaced by pointers to the corresponding elements of otherArray. > +? ? ? ? The identityHashes remain with the pointers rather than with the objects so that > +? ? ? ? the objects in this array should still be properly indexed in any existing hashed > +? ? ? ? structures after the mutation." > +? ? ? ? > -? ? ? ?"This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray.? The identityHashes > remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." > -? ? ? ? > ? ? ? ? self primitiveFailed! > > Item was changed: > ? ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- > ? elementsForwardIdentityTo: otherArray copyHash: copyHash > +? ? ? ?"This primitive performs a bulk mutation, causing all pointers to the elements of the > +? ? ? ? receiver to be replaced by pointers to the corresponding elements of otherArray. > +? ? ? ? If copyHash is true, the identityHashes remain with the pointers rather than with the > +? ? ? ? objects so that the objects in the receiver should still be properly indexed in any > +? ? ? ? existing hashed structures after the mutation.? If copyHash is false, then the hashes > +? ? ? ? of the objects in otherArray remain unchanged.? If you know what you're doing this > +? ? ? ? may indeed be what you want." > +? ? ? ? > -? ? ? ?"This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray.? The identityHashes > remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." > -? ? ? ? > ? ? ? ? self primitiveFailed! > > Item was changed: > ==== ERROR === > > Error: Unrecognized class type > > 4 May 2015 5:47:40.493 pm > > VM: unix - a SmalltalkImage > Image: Squeak3.11alpha [latest update: #8824] > > SecurityManager state: > Restricted: false > FileAccess: true > SocketAccess: true > Working Dir /home/squeaksource > Trusted Dir /home/squeaksource/secure > Untrusted Dir /home/squeaksource/My Squeak > > MCClassDefinition(Object)>>error: > ? ? ? ? Receiver: a MCClassDefinition(Character) > ? ? ? ? Arguments and temporary variables: > ? ? ? ? ? ? ? ? aString:? ? ? ? 'Unrecognized class type' > ? ? ? ? Receiver's instance variables: > ? ? ? ? ? ? ? ? name:? ?#Character > ? ? ? ? ? ? ? ? superclassName:? ? ? ? ?#Magnitude > ? ? ? ? ? ? ? ? variables:? ? ? an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... > ? ? ? ? ? ? ? ? category:? ? ? ?'Collections-Strings' > ? ? ? ? ? ? ? ? type:? ?#immediate > ? ? ? ? ? ? ? ? comment:? ? ? ? 'I represent a character by storing its associated Unicode as an unsig...etc... > ? ? ? ? ? ? ? ? commentStamp:? ?'eem 8/12/2014 14:53' > ? ? ? ? ? ? ? ? traitComposition:? ? ? ?nil > ? ? ? ? ? ? ? ? classTraitComposition:? nil > > MCClassDefinition>>kindOfSubclass > ? ? ? ? Receiver: a MCClassDefinition(Character) > ? ? ? ? Arguments and temporary variables: > > ? ? ? ? Receiver's instance variables: > ? ? ? ? ? ? ? ? name:? ?#Character > ? ? ? ? ? ? ? ? superclassName:? ? ? ? ?#Magnitude > ? ? ? ? ? ? ? ? variables:? ? ? an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... > ? ? ? ? ? ? ? ? category:? ? ? ?'Collections-Strings' > ? ? ? ? ? ? ? ? type:? ?#immediate > ? ? ? ? ? ? ? ? comment:? ? ? ? 'I represent a character by storing its associated Unicode as an unsig...etc... > ? ? ? ? ? ? ? ? commentStamp:? ?'eem 8/12/2014 14:53' > ? ? ? ? ? ? ? ? traitComposition:? ? ? ?nil > ? ? ? ? ? ? ? ? classTraitComposition:? nil > > MCClassDefinition>>printDefinitionOn: > ? ? ? ? Receiver: a MCClassDefinition(Character) > ? ? ? ? Arguments and temporary variables: > ? ? ? ? ? ? ? ? stream:? ? ? ? ?a WriteStream > ? ? ? ? Receiver's instance variables: > ? ? ? ? ? ? ? ? name:? ?#Character > ? ? ? ? ? ? ? ? superclassName:? ? ? ? ?#Magnitude > ? ? ? ? ? ? ? ? variables:? ? ? an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... > ? ? ? ? ? ? ? ? category:? ? ? ?'Collections-Strings' > ? ? ? ? ? ? ? ? type:? ?#immediate > ? ? ? ? ? ? ? ? comment:? ? ? ? 'I represent a character by storing its associated Unicode as an unsig...etc... > ? ? ? ? ? ? ? ? commentStamp:? ?'eem 8/12/2014 14:53' > ? ? ? ? ? ? ? ? traitComposition:? ? ? ?nil > ? ? ? ? ? ? ? ? classTraitComposition:? nil > > [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: > ? ? ? ? Receiver: a MCDiffyTextWriter > ? ? ? ? Arguments and temporary variables: > ? ? ? ? ? ? ? ? definition:? ? ?a WriteStream > ? ? ? ? ? ? ? ? s:? ? ? a MCClassDefinition(Character) > ? ? ? ? Receiver's instance variables: > ? ? ? ? ? ? ? ? stream:? ? ? ? ?a WriteStream > ? ? ? ? ? ? ? ? initStream:? ? ?nil > > > --- The full stack --- > MCClassDefinition(Object)>>error: > MCClassDefinition>>kindOfSubclass > MCClassDefinition>>printDefinitionOn: > [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: > ?- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - > String class(SequenceableCollection class)>>new:streamContents: > String class(SequenceableCollection class)>>streamContents: > MCDiffyTextWriter(MCTextWriter)>>chunkContents: > MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: > MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: > MCClassDefinition>>accept: > [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: > String class(SequenceableCollection class)>>new:streamContents: > String class(SequenceableCollection class)>>streamContents: > MCDiffyTextWriter(MCTextWriter)>>visitInFork: > MCDiffyTextWriter>>writePatchFrom:to: > MCDiffyTextWriter>>writeModification: > [] in MCDiffyTextWriter>>writePatch: > SortedCollection(OrderedCollection)>>do: > MCDiffyTextWriter>>writePatch: > SSDiffyTextWriter>>writePatch: > [] in SSDiffyTextWriter>>writeVersion:for: > BlockClosure>>on:do: > SSDiffyTextWriter>>writeVersion:for: > [] in SSEMailSubscription>>versionAdded:to: > BlockClosure>>on:do: > SSEMailSubscription>>versionAdded:to: > [] in [] in SSProject>>versionAdded: > [] in BlockClosure>>newProcess > > > > > -- > best,Eliot > > From commits at source.squeak.org Mon May 4 20:46:10 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 20:46:12 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.627.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.627.mcz ==================== Summary ==================== Name: Collections.spur-ul.627 Author: eem Time: 4 May 2015, 10:45:12.362 am UUID: b2f54288-1639-463b-9a3a-c94bad8c3d00 Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. =============== Diff against Collections-ul.627 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 4 May 2015 8:46:10.712 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From asqueaker at gmail.com Mon May 4 20:47:47 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 20:47:50 2015 Subject: [squeak-dev] incorrect Shout rendering in ObjectExplorer Message-ID: I noticed that we now have Shout colorization in the code pane of the Explorer. That's nice except when I type the name of an instVar, it renders it the color of error text instead of "instVar" text.. From leves at elte.hu Mon May 4 20:55:05 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon May 4 20:55:09 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: I tried to update an old Spur image, and somehow Character >> #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by update.spur-ul.311) appeared in the image, while loading Collections.spur-tfel.623 from update.spur-mt.310. Assuming that the load order of the packages is untouched, I suspect that the method got merged in from the non-spur branch of Collections somehow. Levente On Mon, 4 May 2015, Levente Uzonyi wrote: > On Mon, 4 May 2015, Eliot Miranda wrote: > >> This breaks my image, dumping it into the emergency evaluator, I *think* >> because the new LetterMask, AlphaNumbericMask and DigitBit variables are >> not handledf correctly by the Spur bootstrap.? Sigh.? So for >> those of you using Spur please *don't* update until I've fixed the >> bootstrap. >> You know, by /not/ releasing, we are delaying because now I am fixing the >> bootstrap to keep up with development, instead of us having released, and >> being able to freely commit on Spur.? We are now wasting >> cycles.? At least I am. > > Multilingual-ul.209 should be loaded before Collections-ul.627, and only then > should Collections-ul.628 be loaded. > > In the regular Trunk, I added an update map which loads Multilingual-ul.209 > and Collections-ul.627 first. (Multilingual was before Collections in the > map, so the load order was already guaranteed). > > Levente > >> >> On Mon, May 4, 2015 at 10:46 AM, wrote: >> Eliot Miranda uploaded a new version of Collections to project The >> Trunk: >> http://source.squeak.org/trunk/Collections.spur-nice.622.mcz >> >> ==================== Summary ==================== >> >> Name: Collections.spur-nice.622 >> Author: eem >> Time: 4 May 2015, 10:45:05.244 am >> UUID: 02450614-82e9-4d33-95fd-3fede06790d2 >> Ancestors: Collections-nice.622, Collections.spur-mt.621 >> >> Collections-nice.622 patched for Spur by >> SpurBootstrapMonticelloPackagePatcher Cog-eem.262 >> >> #toBraceStack: is not used for compiling { } for so long that it's >> really time to get rid of it. >> >> Symbol>>numArgs: does not need to copy self into a temp var. >> >> =============== Diff against Collections-nice.622 =============== >> >> Item was changed: >> ? ----- Method: Array>>elementsExchangeIdentityWith: (in category >> 'converting') ----- >> ? elementsExchangeIdentityWith: otherArray >> +? ? ? ?"This primitive performs a bulk mutation, causing all >> pointers to the elements of the >> +? ? ? ? receiver to be replaced by pointers to the corresponding >> elements of otherArray. >> +? ? ? ? At the same time, all pointers to the elements of otherArray >> are replaced by >> +? ? ? ? pointers to the corresponding elements of this array.? The >> identityHashes remain >> +? ? ? ? with the pointers rather than with the objects so that >> objects in hashed structures >> +? ? ? ? should still be properly indexed after the mutation." >> -? ? ? ?"This primitive performs a bulk mutation, causing all >> pointers to the elements of this array to be replaced by pointers to the >> corresponding elements of otherArray.? At the same time, all >> pointers to the elements of otherArray are replaced by pointers to >> the corresponding elements of this array.? The identityHashes remain with >> the pointers rather than with the objects so that >> objects in hashed structures should still be properly indexed after >> the mutation." >> >> +? ? ? ? >> +? ? ? ?ec == #'bad receiver' ifTrue: >> +? ? ? ? ? ? ? ?[^self error: 'receiver must be of class Array']. >> +? ? ? ?ec == #'bad argument' ifTrue: >> +? ? ? ? ? ? ? ?[^self error: (otherArray class == Array >> +? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ifTrue: ['arg must be >> of class Array'] >> +? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ifFalse: ['receiver >> and argument must have the same size'])]. >> +? ? ? ?ec == #'inappropriate operation' ifTrue: >> +? ? ? ? ? ? ? ?[^self error: 'can''t become immediates such as >> SmallIntegers or Characters']. >> +? ? ? ?ec == #'no modification' ifTrue: >> +? ? ? ? ? ? ? ?[^self error: 'can''t become immutable objects']. >> +? ? ? ?ec == #'object is pinned' ifTrue: >> +? ? ? ? ? ? ? ?[^self error: 'can''t become pinned objects']. >> +? ? ? ?ec == #'insufficient object memory' ifTrue: >> +? ? ? ? ? ? ? ?[Smalltalk garbageCollect < 1048576 ifTrue: >> +? ? ? ? ? ? ? ? ? ? ? ?[Smalltalk growMemoryByAtLeast: 1048576]. >> +? ? ? ? ? ? ? ? ^self elementsExchangeIdentityWith: otherArray]. >> +? ? ? ?self primitiveFailed! >> -? ? ? ? >> -? ? ? ?otherArray class == Array ifFalse: [^ self error: 'arg must >> be array']. >> -? ? ? ?self size = otherArray size ifFalse: [^ self error: 'arrays >> must be same size']. >> -? ? ? ?(self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: >> [^ self error: 'can''t become SmallIntegers']. >> -? ? ? ?(otherArray anySatisfy: [:obj | obj class == SmallInteger]) >> ifTrue: [^ self error: 'can''t become SmallIntegers']. >> -? ? ? ?self with: otherArray do:[:a :b| a == b ifTrue:[^self >> error:'can''t become yourself']]. >> - >> -? ? ? ?"Must have failed because not enough space in forwarding >> table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:).? >> Do GC and try again only once" >> -? ? ? ?(Smalltalk bytesLeft: true) = Smalltalk >> primitiveGarbageCollect >> -? ? ? ? ? ? ? ?ifTrue: [^ self primitiveFailed]. >> -? ? ? ?^ self elementsExchangeIdentityWith: otherArray! >> >> Item was changed: >> ? ----- Method: Array>>elementsForwardIdentityTo: (in category >> 'converting') ----- >> ? elementsForwardIdentityTo: otherArray >> +? ? ? ?"This primitive performs a bulk mutation, causing all >> pointers to the elements of the >> +? ? ? ? receiver to be replaced by pointers to the corresponding >> elements of otherArray. >> +? ? ? ? The identityHashes remain with the pointers rather than with >> the objects so that >> +? ? ? ? the objects in this array should still be properly indexed >> in any existing hashed >> +? ? ? ? structures after the mutation." >> +? ? ? ? >> -? ? ? ?"This primitive performs a bulk mutation, causing all >> pointers to the elements of this array to be replaced by pointers to the >> corresponding elements of otherArray.? The identityHashes >> remain with the pointers rather than with the objects so that the >> objects in this array should still be properly indexed in any existing >> hashed structures after the mutation." >> -? ? ? ? >> ? ? ? ? self primitiveFailed! >> >> Item was changed: >> ? ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in >> category 'converting') ----- >> ? elementsForwardIdentityTo: otherArray copyHash: copyHash >> +? ? ? ?"This primitive performs a bulk mutation, causing all >> pointers to the elements of the >> +? ? ? ? receiver to be replaced by pointers to the corresponding >> elements of otherArray. >> +? ? ? ? If copyHash is true, the identityHashes remain with the >> pointers rather than with the >> +? ? ? ? objects so that the objects in the receiver should still be >> properly indexed in any >> +? ? ? ? existing hashed structures after the mutation.? If copyHash >> is false, then the hashes >> +? ? ? ? of the objects in otherArray remain unchanged.? If you know >> what you're doing this >> +? ? ? ? may indeed be what you want." >> +? ? ? ? >> -? ? ? ?"This primitive performs a bulk mutation, causing all >> pointers to the elements of this array to be replaced by pointers to the >> corresponding elements of otherArray.? The identityHashes >> remain with the pointers rather than with the objects so that the >> objects in this array should still be properly indexed in any existing >> hashed structures after the mutation." >> -? ? ? ? >> ? ? ? ? self primitiveFailed! >> >> Item was changed: >> ==== ERROR === >> >> Error: Unrecognized class type >> >> 4 May 2015 5:47:40.493 pm >> >> VM: unix - a SmalltalkImage >> Image: Squeak3.11alpha [latest update: #8824] >> >> SecurityManager state: >> Restricted: false >> FileAccess: true >> SocketAccess: true >> Working Dir /home/squeaksource >> Trusted Dir /home/squeaksource/secure >> Untrusted Dir /home/squeaksource/My Squeak >> >> MCClassDefinition(Object)>>error: >> ? ? ? ? Receiver: a MCClassDefinition(Character) >> ? ? ? ? Arguments and temporary variables: >> ? ? ? ? ? ? ? ? aString:? ? ? ? 'Unrecognized class type' >> ? ? ? ? Receiver's instance variables: >> ? ? ? ? ? ? ? ? name:? ?#Character >> ? ? ? ? ? ? ? ? superclassName:? ? ? ? ?#Magnitude >> ? ? ? ? ? ? ? ? variables:? ? ? an OrderedCollection(a >> MCClassVariableDefinition(CharacterTable) a M...etc... >> ? ? ? ? ? ? ? ? category:? ? ? ?'Collections-Strings' >> ? ? ? ? ? ? ? ? type:? ?#immediate >> ? ? ? ? ? ? ? ? comment:? ? ? ? 'I represent a character by storing >> its associated Unicode as an unsig...etc... >> ? ? ? ? ? ? ? ? commentStamp:? ?'eem 8/12/2014 14:53' >> ? ? ? ? ? ? ? ? traitComposition:? ? ? ?nil >> ? ? ? ? ? ? ? ? classTraitComposition:? nil >> >> MCClassDefinition>>kindOfSubclass >> ? ? ? ? Receiver: a MCClassDefinition(Character) >> ? ? ? ? Arguments and temporary variables: >> >> ? ? ? ? Receiver's instance variables: >> ? ? ? ? ? ? ? ? name:? ?#Character >> ? ? ? ? ? ? ? ? superclassName:? ? ? ? ?#Magnitude >> ? ? ? ? ? ? ? ? variables:? ? ? an OrderedCollection(a >> MCClassVariableDefinition(CharacterTable) a M...etc... >> ? ? ? ? ? ? ? ? category:? ? ? ?'Collections-Strings' >> ? ? ? ? ? ? ? ? type:? ?#immediate >> ? ? ? ? ? ? ? ? comment:? ? ? ? 'I represent a character by storing >> its associated Unicode as an unsig...etc... >> ? ? ? ? ? ? ? ? commentStamp:? ?'eem 8/12/2014 14:53' >> ? ? ? ? ? ? ? ? traitComposition:? ? ? ?nil >> ? ? ? ? ? ? ? ? classTraitComposition:? nil >> >> MCClassDefinition>>printDefinitionOn: >> ? ? ? ? Receiver: a MCClassDefinition(Character) >> ? ? ? ? Arguments and temporary variables: >> ? ? ? ? ? ? ? ? stream:? ? ? ? ?a WriteStream >> ? ? ? ? Receiver's instance variables: >> ? ? ? ? ? ? ? ? name:? ?#Character >> ? ? ? ? ? ? ? ? superclassName:? ? ? ? ?#Magnitude >> ? ? ? ? ? ? ? ? variables:? ? ? an OrderedCollection(a >> MCClassVariableDefinition(CharacterTable) a M...etc... >> ? ? ? ? ? ? ? ? category:? ? ? ?'Collections-Strings' >> ? ? ? ? ? ? ? ? type:? ?#immediate >> ? ? ? ? ? ? ? ? comment:? ? ? ? 'I represent a character by storing >> its associated Unicode as an unsig...etc... >> ? ? ? ? ? ? ? ? commentStamp:? ?'eem 8/12/2014 14:53' >> ? ? ? ? ? ? ? ? traitComposition:? ? ? ?nil >> ? ? ? ? ? ? ? ? classTraitComposition:? nil >> >> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >> ? ? ? ? Receiver: a MCDiffyTextWriter >> ? ? ? ? Arguments and temporary variables: >> ? ? ? ? ? ? ? ? definition:? ? ?a WriteStream >> ? ? ? ? ? ? ? ? s:? ? ? a MCClassDefinition(Character) >> ? ? ? ? Receiver's instance variables: >> ? ? ? ? ? ? ? ? stream:? ? ? ? ?a WriteStream >> ? ? ? ? ? ? ? ? initStream:? ? ?nil >> >> >> --- The full stack --- >> MCClassDefinition(Object)>>error: >> MCClassDefinition>>kindOfSubclass >> MCClassDefinition>>printDefinitionOn: >> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >> ?- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >> String class(SequenceableCollection class)>>new:streamContents: >> String class(SequenceableCollection class)>>streamContents: >> MCDiffyTextWriter(MCTextWriter)>>chunkContents: >> MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >> MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: >> MCClassDefinition>>accept: >> [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: >> String class(SequenceableCollection class)>>new:streamContents: >> String class(SequenceableCollection class)>>streamContents: >> MCDiffyTextWriter(MCTextWriter)>>visitInFork: >> MCDiffyTextWriter>>writePatchFrom:to: >> MCDiffyTextWriter>>writeModification: >> [] in MCDiffyTextWriter>>writePatch: >> SortedCollection(OrderedCollection)>>do: >> MCDiffyTextWriter>>writePatch: >> SSDiffyTextWriter>>writePatch: >> [] in SSDiffyTextWriter>>writeVersion:for: >> BlockClosure>>on:do: >> SSDiffyTextWriter>>writeVersion:for: >> [] in SSEMailSubscription>>versionAdded:to: >> BlockClosure>>on:do: >> SSEMailSubscription>>versionAdded:to: >> [] in [] in SSProject>>versionAdded: >> [] in BlockClosure>>newProcess >> >> >> >> >> -- >> best,Eliot >> > From leves at elte.hu Mon May 4 20:56:22 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon May 4 20:56:26 2015 Subject: [squeak-dev] incorrect Shout rendering in ObjectExplorer In-Reply-To: References: Message-ID: In an Explorer you can't evaluate an expression in the context of an Object. That's what an Inspector is for. Levente On Mon, 4 May 2015, Chris Muller wrote: > I noticed that we now have Shout colorization in the code pane of the Explorer. > > That's nice except when I type the name of an instVar, it renders it > the color of error text instead of "instVar" text.. > > From herbertkoenig at gmx.net Mon May 4 21:06:54 2015 From: herbertkoenig at gmx.net (=?windows-1252?Q?Herbert_K=F6nig?=) Date: Mon May 4 21:06:58 2015 Subject: [squeak-dev] incorrect Shout rendering in ObjectExplorer In-Reply-To: References: Message-ID: <5547DF6E.5060106@gmx.net> you evaluate it in the context of the selected object. I find that more useful than having to prepend my evaluation with the name of the instvar like in the Inspector. Cheers, Herbert Am 04.05.2015 um 22:56 schrieb Levente Uzonyi: > In an Explorer you can't evaluate an expression in the context of an > Object. That's what an Inspector is for. > > Levente > > On Mon, 4 May 2015, Chris Muller wrote: > >> I noticed that we now have Shout colorization in the code pane of the >> Explorer. >> >> That's nice except when I type the name of an instVar, it renders it >> the color of error text instead of "instVar" text.. >> >> > From eliot.miranda at gmail.com Mon May 4 21:08:15 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon May 4 21:08:18 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Mon, May 4, 2015 at 1:41 PM, Levente Uzonyi wrote: > On Mon, 4 May 2015, Eliot Miranda wrote: > > This breaks my image, dumping it into the emergency evaluator, I *think* >> because the new LetterMask, AlphaNumbericMask and DigitBit variables are >> not handledf correctly by the Spur bootstrap. Sigh. So for >> those of you using Spur please *don't* update until I've fixed the >> bootstrap. >> You know, by /not/ releasing, we are delaying because now I am fixing the >> bootstrap to keep up with development, instead of us having released, and >> being able to freely commit on Spur. We are now wasting >> cycles. At least I am. >> > > Multilingual-ul.209 should be loaded before Collections-ul.627, and only > then should Collections-ul.628 be loaded. > Thanks, that got me unblocked. > > In the regular Trunk, I added an update map which loads > Multilingual-ul.209 and Collections-ul.627 first. (Multilingual was before > Collections in the map, so the load order was already guaranteed). The Monticello package patching part of the bootstrap creates corresponding update.spur updates. Which specific update is the one that ensures safety? I may have missed it through a bug. BTW, I think the multiple ancestry that one ends up with in Spur packages, e.g. that Collections.spur-abc.123 inherits from both Collections.spur-xyz-122 and Collections.abc-123, causes issues for the update merge. > > Levente > > > >> On Mon, May 4, 2015 at 10:46 AM, wrote: >> Eliot Miranda uploaded a new version of Collections to project The >> Trunk: >> http://source.squeak.org/trunk/Collections.spur-nice.622.mcz >> >> ==================== Summary ==================== >> >> Name: Collections.spur-nice.622 >> Author: eem >> Time: 4 May 2015, 10:45:05.244 am >> UUID: 02450614-82e9-4d33-95fd-3fede06790d2 >> Ancestors: Collections-nice.622, Collections.spur-mt.621 >> >> Collections-nice.622 patched for Spur by >> SpurBootstrapMonticelloPackagePatcher Cog-eem.262 >> >> #toBraceStack: is not used for compiling { } for so long that it's >> really time to get rid of it. >> >> Symbol>>numArgs: does not need to copy self into a temp var. >> >> =============== Diff against Collections-nice.622 =============== >> >> Item was changed: >> ----- Method: Array>>elementsExchangeIdentityWith: (in category >> 'converting') ----- >> elementsExchangeIdentityWith: otherArray >> + "This primitive performs a bulk mutation, causing all >> pointers to the elements of the >> + receiver to be replaced by pointers to the corresponding >> elements of otherArray. >> + At the same time, all pointers to the elements of >> otherArray are replaced by >> + pointers to the corresponding elements of this array. The >> identityHashes remain >> + with the pointers rather than with the objects so that >> objects in hashed structures >> + should still be properly indexed after the mutation." >> - "This primitive performs a bulk mutation, causing all >> pointers to the elements of this array to be replaced by pointers to the >> corresponding elements of otherArray. At the same time, all >> pointers to the elements of otherArray are replaced by pointers to >> the corresponding elements of this array. The identityHashes remain with >> the pointers rather than with the objects so that >> objects in hashed structures should still be properly indexed after >> the mutation." >> >> + >> + ec == #'bad receiver' ifTrue: >> + [^self error: 'receiver must be of class Array']. >> + ec == #'bad argument' ifTrue: >> + [^self error: (otherArray class == Array >> + ifTrue: ['arg must >> be of class Array'] >> + ifFalse: ['receiver >> and argument must have the same size'])]. >> + ec == #'inappropriate operation' ifTrue: >> + [^self error: 'can''t become immediates such as >> SmallIntegers or Characters']. >> + ec == #'no modification' ifTrue: >> + [^self error: 'can''t become immutable objects']. >> + ec == #'object is pinned' ifTrue: >> + [^self error: 'can''t become pinned objects']. >> + ec == #'insufficient object memory' ifTrue: >> + [Smalltalk garbageCollect < 1048576 ifTrue: >> + [Smalltalk growMemoryByAtLeast: 1048576]. >> + ^self elementsExchangeIdentityWith: otherArray]. >> + self primitiveFailed! >> - >> - otherArray class == Array ifFalse: [^ self error: 'arg must >> be array']. >> - self size = otherArray size ifFalse: [^ self error: 'arrays >> must be same size']. >> - (self anySatisfy: [:obj | obj class == SmallInteger]) >> ifTrue: [^ self error: 'can''t become SmallIntegers']. >> - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) >> ifTrue: [^ self error: 'can''t become SmallIntegers']. >> - self with: otherArray do:[:a :b| a == b ifTrue:[^self >> error:'can''t become yourself']]. >> - >> - "Must have failed because not enough space in forwarding >> table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). >> Do GC and try again only once" >> - (Smalltalk bytesLeft: true) = Smalltalk >> primitiveGarbageCollect >> - ifTrue: [^ self primitiveFailed]. >> - ^ self elementsExchangeIdentityWith: otherArray! >> >> Item was changed: >> ----- Method: Array>>elementsForwardIdentityTo: (in category >> 'converting') ----- >> elementsForwardIdentityTo: otherArray >> + "This primitive performs a bulk mutation, causing all >> pointers to the elements of the >> + receiver to be replaced by pointers to the corresponding >> elements of otherArray. >> + The identityHashes remain with the pointers rather than >> with the objects so that >> + the objects in this array should still be properly indexed >> in any existing hashed >> + structures after the mutation." >> + >> - "This primitive performs a bulk mutation, causing all >> pointers to the elements of this array to be replaced by pointers to the >> corresponding elements of otherArray. The identityHashes >> remain with the pointers rather than with the objects so that the >> objects in this array should still be properly indexed in any existing >> hashed structures after the mutation." >> - >> self primitiveFailed! >> >> Item was changed: >> ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in >> category 'converting') ----- >> elementsForwardIdentityTo: otherArray copyHash: copyHash >> + "This primitive performs a bulk mutation, causing all >> pointers to the elements of the >> + receiver to be replaced by pointers to the corresponding >> elements of otherArray. >> + If copyHash is true, the identityHashes remain with the >> pointers rather than with the >> + objects so that the objects in the receiver should still >> be properly indexed in any >> + existing hashed structures after the mutation. If >> copyHash is false, then the hashes >> + of the objects in otherArray remain unchanged. If you >> know what you're doing this >> + may indeed be what you want." >> + >> - "This primitive performs a bulk mutation, causing all >> pointers to the elements of this array to be replaced by pointers to the >> corresponding elements of otherArray. The identityHashes >> remain with the pointers rather than with the objects so that the >> objects in this array should still be properly indexed in any existing >> hashed structures after the mutation." >> - >> self primitiveFailed! >> >> Item was changed: >> ==== ERROR === >> >> Error: Unrecognized class type >> >> 4 May 2015 5:47:40.493 pm >> >> VM: unix - a SmalltalkImage >> Image: Squeak3.11alpha [latest update: #8824] >> >> SecurityManager state: >> Restricted: false >> FileAccess: true >> SocketAccess: true >> Working Dir /home/squeaksource >> Trusted Dir /home/squeaksource/secure >> Untrusted Dir /home/squeaksource/My Squeak >> >> MCClassDefinition(Object)>>error: >> Receiver: a MCClassDefinition(Character) >> Arguments and temporary variables: >> aString: 'Unrecognized class type' >> Receiver's instance variables: >> name: #Character >> superclassName: #Magnitude >> variables: an OrderedCollection(a >> MCClassVariableDefinition(CharacterTable) a M...etc... >> category: 'Collections-Strings' >> type: #immediate >> comment: 'I represent a character by storing >> its associated Unicode as an unsig...etc... >> commentStamp: 'eem 8/12/2014 14:53' >> traitComposition: nil >> classTraitComposition: nil >> >> MCClassDefinition>>kindOfSubclass >> Receiver: a MCClassDefinition(Character) >> Arguments and temporary variables: >> >> Receiver's instance variables: >> name: #Character >> superclassName: #Magnitude >> variables: an OrderedCollection(a >> MCClassVariableDefinition(CharacterTable) a M...etc... >> category: 'Collections-Strings' >> type: #immediate >> comment: 'I represent a character by storing >> its associated Unicode as an unsig...etc... >> commentStamp: 'eem 8/12/2014 14:53' >> traitComposition: nil >> classTraitComposition: nil >> >> MCClassDefinition>>printDefinitionOn: >> Receiver: a MCClassDefinition(Character) >> Arguments and temporary variables: >> stream: a WriteStream >> Receiver's instance variables: >> name: #Character >> superclassName: #Magnitude >> variables: an OrderedCollection(a >> MCClassVariableDefinition(CharacterTable) a M...etc... >> category: 'Collections-Strings' >> type: #immediate >> comment: 'I represent a character by storing >> its associated Unicode as an unsig...etc... >> commentStamp: 'eem 8/12/2014 14:53' >> traitComposition: nil >> classTraitComposition: nil >> >> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >> Receiver: a MCDiffyTextWriter >> Arguments and temporary variables: >> definition: a WriteStream >> s: a MCClassDefinition(Character) >> Receiver's instance variables: >> stream: a WriteStream >> initStream: nil >> >> >> --- The full stack --- >> MCClassDefinition(Object)>>error: >> MCClassDefinition>>kindOfSubclass >> MCClassDefinition>>printDefinitionOn: >> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >> String class(SequenceableCollection class)>>new:streamContents: >> String class(SequenceableCollection class)>>streamContents: >> MCDiffyTextWriter(MCTextWriter)>>chunkContents: >> MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >> MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: >> MCClassDefinition>>accept: >> [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: >> String class(SequenceableCollection class)>>new:streamContents: >> String class(SequenceableCollection class)>>streamContents: >> MCDiffyTextWriter(MCTextWriter)>>visitInFork: >> MCDiffyTextWriter>>writePatchFrom:to: >> MCDiffyTextWriter>>writeModification: >> [] in MCDiffyTextWriter>>writePatch: >> SortedCollection(OrderedCollection)>>do: >> MCDiffyTextWriter>>writePatch: >> SSDiffyTextWriter>>writePatch: >> [] in SSDiffyTextWriter>>writeVersion:for: >> BlockClosure>>on:do: >> SSDiffyTextWriter>>writeVersion:for: >> [] in SSEMailSubscription>>versionAdded:to: >> BlockClosure>>on:do: >> SSEMailSubscription>>versionAdded:to: >> [] in [] in SSProject>>versionAdded: >> [] in BlockClosure>>newProcess >> >> >> >> >> -- >> best,Eliot >> >> > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/4841ac0b/attachment-0001.htm From eliot.miranda at gmail.com Mon May 4 21:08:58 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon May 4 21:09:00 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Mon, May 4, 2015 at 1:55 PM, Levente Uzonyi wrote: > I tried to update an old Spur image, and somehow Character >> > #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by > update.spur-ul.311) appeared in the image, while loading > Collections.spur-tfel.623 from update.spur-mt.310. > Assuming that the load order of the packages is untouched, I suspect that > the method got merged in from the non-spur branch of Collections somehow. I think the multiple ancestry that one ends up with in Spur packages, e.g. that Collections.spur-abc.123 inherits from both Collections.spur-xyz-122 and Collections.abc-123, causes issues for the update merge. I wonder whether that could be the cause? > > Levente > > > On Mon, 4 May 2015, Levente Uzonyi wrote: > > On Mon, 4 May 2015, Eliot Miranda wrote: >> >> This breaks my image, dumping it into the emergency evaluator, I *think* >>> because the new LetterMask, AlphaNumbericMask and DigitBit variables are >>> not handledf correctly by the Spur bootstrap. Sigh. So for >>> those of you using Spur please *don't* update until I've fixed the >>> bootstrap. >>> You know, by /not/ releasing, we are delaying because now I am fixing >>> the bootstrap to keep up with development, instead of us having released, >>> and being able to freely commit on Spur. We are now wasting >>> cycles. At least I am. >>> >> >> Multilingual-ul.209 should be loaded before Collections-ul.627, and only >> then should Collections-ul.628 be loaded. >> >> In the regular Trunk, I added an update map which loads >> Multilingual-ul.209 and Collections-ul.627 first. (Multilingual was before >> Collections in the map, so the load order was already guaranteed). >> >> Levente >> >> >>> On Mon, May 4, 2015 at 10:46 AM, wrote: >>> Eliot Miranda uploaded a new version of Collections to project The >>> Trunk: >>> http://source.squeak.org/trunk/Collections.spur-nice.622.mcz >>> >>> ==================== Summary ==================== >>> >>> Name: Collections.spur-nice.622 >>> Author: eem >>> Time: 4 May 2015, 10:45:05.244 am >>> UUID: 02450614-82e9-4d33-95fd-3fede06790d2 >>> Ancestors: Collections-nice.622, Collections.spur-mt.621 >>> >>> Collections-nice.622 patched for Spur by >>> SpurBootstrapMonticelloPackagePatcher Cog-eem.262 >>> >>> #toBraceStack: is not used for compiling { } for so long that it's >>> really time to get rid of it. >>> >>> Symbol>>numArgs: does not need to copy self into a temp var. >>> >>> =============== Diff against Collections-nice.622 =============== >>> >>> Item was changed: >>> ----- Method: Array>>elementsExchangeIdentityWith: (in category >>> 'converting') ----- >>> elementsExchangeIdentityWith: otherArray >>> + "This primitive performs a bulk mutation, causing all >>> pointers to the elements of the >>> + receiver to be replaced by pointers to the corresponding >>> elements of otherArray. >>> + At the same time, all pointers to the elements of >>> otherArray are replaced by >>> + pointers to the corresponding elements of this array. >>> The identityHashes remain >>> + with the pointers rather than with the objects so that >>> objects in hashed structures >>> + should still be properly indexed after the mutation." >>> - "This primitive performs a bulk mutation, causing all >>> pointers to the elements of this array to be replaced by pointers to the >>> corresponding elements of otherArray. At the same time, all >>> pointers to the elements of otherArray are replaced by pointers to >>> the corresponding elements of this array. The identityHashes remain with >>> the pointers rather than with the objects so that >>> objects in hashed structures should still be properly indexed >>> after the mutation." >>> >>> + >>> + ec == #'bad receiver' ifTrue: >>> + [^self error: 'receiver must be of class Array']. >>> + ec == #'bad argument' ifTrue: >>> + [^self error: (otherArray class == Array >>> + ifTrue: ['arg must >>> be of class Array'] >>> + ifFalse: >>> ['receiver and argument must have the same size'])]. >>> + ec == #'inappropriate operation' ifTrue: >>> + [^self error: 'can''t become immediates such as >>> SmallIntegers or Characters']. >>> + ec == #'no modification' ifTrue: >>> + [^self error: 'can''t become immutable objects']. >>> + ec == #'object is pinned' ifTrue: >>> + [^self error: 'can''t become pinned objects']. >>> + ec == #'insufficient object memory' ifTrue: >>> + [Smalltalk garbageCollect < 1048576 ifTrue: >>> + [Smalltalk growMemoryByAtLeast: 1048576]. >>> + ^self elementsExchangeIdentityWith: otherArray]. >>> + self primitiveFailed! >>> - >>> - otherArray class == Array ifFalse: [^ self error: 'arg >>> must be array']. >>> - self size = otherArray size ifFalse: [^ self error: >>> 'arrays must be same size']. >>> - (self anySatisfy: [:obj | obj class == SmallInteger]) >>> ifTrue: [^ self error: 'can''t become SmallIntegers']. >>> - (otherArray anySatisfy: [:obj | obj class == >>> SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. >>> - self with: otherArray do:[:a :b| a == b ifTrue:[^self >>> error:'can''t become yourself']]. >>> - >>> - "Must have failed because not enough space in forwarding >>> table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). >>> Do GC and try again only once" >>> - (Smalltalk bytesLeft: true) = Smalltalk >>> primitiveGarbageCollect >>> - ifTrue: [^ self primitiveFailed]. >>> - ^ self elementsExchangeIdentityWith: otherArray! >>> >>> Item was changed: >>> ----- Method: Array>>elementsForwardIdentityTo: (in category >>> 'converting') ----- >>> elementsForwardIdentityTo: otherArray >>> + "This primitive performs a bulk mutation, causing all >>> pointers to the elements of the >>> + receiver to be replaced by pointers to the corresponding >>> elements of otherArray. >>> + The identityHashes remain with the pointers rather than >>> with the objects so that >>> + the objects in this array should still be properly >>> indexed in any existing hashed >>> + structures after the mutation." >>> + >>> - "This primitive performs a bulk mutation, causing all >>> pointers to the elements of this array to be replaced by pointers to the >>> corresponding elements of otherArray. The identityHashes >>> remain with the pointers rather than with the objects so that the >>> objects in this array should still be properly indexed in any existing >>> hashed structures after the mutation." >>> - >>> self primitiveFailed! >>> >>> Item was changed: >>> ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in >>> category 'converting') ----- >>> elementsForwardIdentityTo: otherArray copyHash: copyHash >>> + "This primitive performs a bulk mutation, causing all >>> pointers to the elements of the >>> + receiver to be replaced by pointers to the corresponding >>> elements of otherArray. >>> + If copyHash is true, the identityHashes remain with the >>> pointers rather than with the >>> + objects so that the objects in the receiver should still >>> be properly indexed in any >>> + existing hashed structures after the mutation. If >>> copyHash is false, then the hashes >>> + of the objects in otherArray remain unchanged. If you >>> know what you're doing this >>> + may indeed be what you want." >>> + >>> - "This primitive performs a bulk mutation, causing all >>> pointers to the elements of this array to be replaced by pointers to the >>> corresponding elements of otherArray. The identityHashes >>> remain with the pointers rather than with the objects so that the >>> objects in this array should still be properly indexed in any existing >>> hashed structures after the mutation." >>> - >>> self primitiveFailed! >>> >>> Item was changed: >>> ==== ERROR === >>> >>> Error: Unrecognized class type >>> >>> 4 May 2015 5:47:40.493 pm >>> >>> VM: unix - a SmalltalkImage >>> Image: Squeak3.11alpha [latest update: #8824] >>> >>> SecurityManager state: >>> Restricted: false >>> FileAccess: true >>> SocketAccess: true >>> Working Dir /home/squeaksource >>> Trusted Dir /home/squeaksource/secure >>> Untrusted Dir /home/squeaksource/My Squeak >>> >>> MCClassDefinition(Object)>>error: >>> Receiver: a MCClassDefinition(Character) >>> Arguments and temporary variables: >>> aString: 'Unrecognized class type' >>> Receiver's instance variables: >>> name: #Character >>> superclassName: #Magnitude >>> variables: an OrderedCollection(a >>> MCClassVariableDefinition(CharacterTable) a M...etc... >>> category: 'Collections-Strings' >>> type: #immediate >>> comment: 'I represent a character by >>> storing its associated Unicode as an unsig...etc... >>> commentStamp: 'eem 8/12/2014 14:53' >>> traitComposition: nil >>> classTraitComposition: nil >>> >>> MCClassDefinition>>kindOfSubclass >>> Receiver: a MCClassDefinition(Character) >>> Arguments and temporary variables: >>> >>> Receiver's instance variables: >>> name: #Character >>> superclassName: #Magnitude >>> variables: an OrderedCollection(a >>> MCClassVariableDefinition(CharacterTable) a M...etc... >>> category: 'Collections-Strings' >>> type: #immediate >>> comment: 'I represent a character by >>> storing its associated Unicode as an unsig...etc... >>> commentStamp: 'eem 8/12/2014 14:53' >>> traitComposition: nil >>> classTraitComposition: nil >>> >>> MCClassDefinition>>printDefinitionOn: >>> Receiver: a MCClassDefinition(Character) >>> Arguments and temporary variables: >>> stream: a WriteStream >>> Receiver's instance variables: >>> name: #Character >>> superclassName: #Magnitude >>> variables: an OrderedCollection(a >>> MCClassVariableDefinition(CharacterTable) a M...etc... >>> category: 'Collections-Strings' >>> type: #immediate >>> comment: 'I represent a character by >>> storing its associated Unicode as an unsig...etc... >>> commentStamp: 'eem 8/12/2014 14:53' >>> traitComposition: nil >>> classTraitComposition: nil >>> >>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>> Receiver: a MCDiffyTextWriter >>> Arguments and temporary variables: >>> definition: a WriteStream >>> s: a MCClassDefinition(Character) >>> Receiver's instance variables: >>> stream: a WriteStream >>> initStream: nil >>> >>> >>> --- The full stack --- >>> MCClassDefinition(Object)>>error: >>> MCClassDefinition>>kindOfSubclass >>> MCClassDefinition>>printDefinitionOn: >>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >>> String class(SequenceableCollection class)>>new:streamContents: >>> String class(SequenceableCollection class)>>streamContents: >>> MCDiffyTextWriter(MCTextWriter)>>chunkContents: >>> MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>> MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: >>> MCClassDefinition>>accept: >>> [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>> String class(SequenceableCollection class)>>new:streamContents: >>> String class(SequenceableCollection class)>>streamContents: >>> MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>> MCDiffyTextWriter>>writePatchFrom:to: >>> MCDiffyTextWriter>>writeModification: >>> [] in MCDiffyTextWriter>>writePatch: >>> SortedCollection(OrderedCollection)>>do: >>> MCDiffyTextWriter>>writePatch: >>> SSDiffyTextWriter>>writePatch: >>> [] in SSDiffyTextWriter>>writeVersion:for: >>> BlockClosure>>on:do: >>> SSDiffyTextWriter>>writeVersion:for: >>> [] in SSEMailSubscription>>versionAdded:to: >>> BlockClosure>>on:do: >>> SSEMailSubscription>>versionAdded:to: >>> [] in [] in SSProject>>versionAdded: >>> [] in BlockClosure>>newProcess >>> >>> >>> >>> >>> -- >>> best,Eliot >>> >>> > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/d29cf565/attachment.htm From asqueaker at gmail.com Mon May 4 21:12:05 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 21:12:08 2015 Subject: [squeak-dev] incorrect Shout rendering in ObjectExplorer In-Reply-To: References: Message-ID: On Mon, May 4, 2015 at 3:56 PM, Levente Uzonyi wrote: > In an Explorer you can't evaluate an expression in the context of an Object. > That's what an Inspector is for. Huh? If I explore, say, Smalltalk, and select the "root" row of the explorer, then I can evaluate any expressoins I want in the context of the selected object, Smalltalk. Likewise, I can directly access the selected objects instVars. For example, while the root is selected I can evaluate "globals class" and it tells me its an Environment. The problem, whether I'm in an Explorer or an Inspector, is the new Shout color rendering is rendering instVars in the color I've chosen for "invalid" (in the Shout style table). See picture. I style my "invalid" code an ugly magenta, so it stands out. But I don't want that when its not invalid, of course.. -------------- next part -------------- A non-text attachment was scrubbed... Name: SmalltalkImage.png Type: image/png Size: 8090 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/4b67ca73/SmalltalkImage.png From asqueaker at gmail.com Mon May 4 21:18:47 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 21:18:50 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: One thing I don't like about the scattered preferences is how the preference API is no longer supported. I have a script which sets up my preferred preferences, I tried to write: Preferences disable: #showMessageIcons just like I can for "normal" preferences, however, the above doesn't work and doesn't report an error... On Sun, May 3, 2015 at 6:50 AM, karl ramberg wrote: > I mean this more like: when we have separate preferences for every widget it > will be hard,confusing and tedious to hunt down every setting for color and > corner rounding etc. to change the look of the system. > Even if the PreferenceBrowser access them all, it will become overwhelming > with several hundred preferences > > On Sun, May 3, 2015 at 11:56 AM, Marcel Taeumel > wrote: >> >> Why? No "user" should have to scan classes. The Preferences Browser is for >> that. It integrates all scattered preferences. And it supports search as >> well as browsing the acutal senders. >> >> It's a good thing that each new package/class can bring new preferences >> with >> it. >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: >> http://forum.world.st/The-Trunk-Morphic-kfr-958-mcz-tp4823778p4823948.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> > > > > From asqueaker at gmail.com Mon May 4 21:27:28 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 4 21:27:30 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: On Mon, May 4, 2015 at 4:18 PM, Chris Muller wrote: > One thing I don't like about the scattered preferences is how the > preference API is no longer supported. I have a script which sets up > my preferred preferences, I tried to write: > > Preferences disable: #showMessageIcons > > just like I can for "normal" preferences, however, the above doesn't > work and doesn't report an error... In fact, it can even cause a duplicate preference to be added (see picture). -------------- next part -------------- A non-text attachment was scrubbed... Name: two-of-the-same-prefs.png Type: image/png Size: 15568 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/f362cd32/two-of-the-same-prefs.png From cunningham.cb at gmail.com Mon May 4 21:54:04 2015 From: cunningham.cb at gmail.com (Chris Cunningham) Date: Mon May 4 21:54:07 2015 Subject: [squeak-dev] incorrect Shout rendering in ObjectExplorer In-Reply-To: References: Message-ID: That is probably due to Shout not knowing what variables are available/bound to the explorer pane. To do that correctly, the available variables should change each time you change the selection in the list pane. In your example, globals should be a valid variable and colored as such. But as soon as you select, say, globals, then the text that you have written below should show globals as invalid again. I suspect there may be some interesting code to play with in getting that right. -cbc On Mon, May 4, 2015 at 2:12 PM, Chris Muller wrote: > On Mon, May 4, 2015 at 3:56 PM, Levente Uzonyi wrote: > > In an Explorer you can't evaluate an expression in the context of an > Object. > > That's what an Inspector is for. > > Huh? If I explore, say, Smalltalk, and select the "root" row of the > explorer, then I can evaluate any expressoins I want in the context of > the selected object, Smalltalk. > > Likewise, I can directly access the selected objects instVars. For > example, while the root is selected I can evaluate "globals class" and > it tells me its an Environment. > > The problem, whether I'm in an Explorer or an Inspector, is the new > Shout color rendering is rendering instVars in the color I've chosen > for "invalid" (in the Shout style table). > > See picture. I style my "invalid" code an ugly magenta, so it stands > out. But I don't want that when its not invalid, of course.. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/06e48796/attachment.htm From commits at source.squeak.org Mon May 4 21:55:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 21:55:07 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150504215504.32329.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008254.html Name: System-topa.734 Ancestors: System-topa.733 (typo) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008255.html Name: Collections.spur-tfel.623 Ancestors: Collections-tfel.623, Collections.spur-nice.622 Collections-tfel.623 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008256.html Name: Collections.spur-tfel.624 Ancestors: Collections-tfel.624, Collections.spur-tfel.623 Collections-tfel.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008257.html Name: Collections.spur-nice.622 Ancestors: Collections-nice.622, Collections.spur-mt.621 Collections-nice.622 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 #toBraceStack: is not used for compiling { } for so long that it's really time to get rid of it. Symbol>>numArgs: does not need to copy self into a temp var. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008258.html Name: Collections.spur-mt.625 Ancestors: Collections-mt.625 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Speed-up #endsWith: for strings. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008259.html Name: Collections.spur-mt.626 Ancestors: Collections-mt.626, Collections.spur-mt.625 Collections-mt.626 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008260.html Name: Collections.spur-ul.627 Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008261.html Name: Collections.spur-ul.628 Ancestors: Collections-ul.628, Collections.spur-ul.627 Collections-ul.628 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.625. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008262.html Name: Collections.spur-mt.629 Ancestors: Collections-mt.629 Collections-mt.629 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008263.html Name: Collections.spur-mt.630 Ancestors: Collections-mt.630, Collections.spur-mt.629 Collections-mt.630 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HTML escaping added to html read/writer ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008264.html Name: Collections.spur-mt.631 Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HtmlReadWriter: support for comments added, list of ignored tags added ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008265.html Name: Kernel.spur-nice.921 Ancestors: Kernel-nice.921, Kernel.spur-topa.920 Kernel-nice.921 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Provide an exact version for #floorLog: for those Number using exact arithmetic (as proposed in inbox Kernel-nice.721 / 11 December 2012). Previous version was not exact, otherwise this count would have been zero: (-300 to: -1) count: [:n | n ~= ((10 raisedTo: n) floorLog: 10)]. Note that this won't make #log: exact, and could lead to disagreement between the two functions. However, old behavior compatible with log: is still possible by passing the radix argument asFloat, so this is not a real problem. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008266.html Name: Kernel.spur-nice.922 Ancestors: Kernel-nice.922, Kernel.spur-nice.921 Kernel-nice.922 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Remove an un-necessary inst. var. shadowing (inbox Kernel-nice.745 7 March 2013) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008267.html Name: Kernel.spur-nice.923 Ancestors: Kernel-nice.923, Kernel.spur-nice.922 Kernel-nice.923 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Use an intermediate abstract Float representation (sign, exponent, significand) in order to convert single precision bits to double precision bits rather than attempting the conversion by direct bit manipulations. This lead to simpler code, because it is like a semantic bit manipulation rather than a raw bit manipulation. And this also lead to faster code on 32 bits interpreter/COG/Spur VM thanks to avoidance of LargeInteger (was Kernel-nice.893 / 24 December 2014) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008268.html Name: Kernel.spur-mt.924 Ancestors: Kernel-mt.924 Kernel-mt.924 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 ValueHolder: Only notify about changed contents if contents actually changed. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008269.html Name: System.spur-cmm.728 Ancestors: System-cmm.728 System-cmm.728 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Restored the much safer version of Preferences class>>#preferenceAt:ifAbsent:. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008270.html Name: System.spur-kfr.729 Ancestors: System-kfr.729, System.spur-cmm.728 System-kfr.729 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Add a 'refresh this menu' item to the Standard System Fonts menu, so it can update to reflect the current selected fonts ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008271.html Name: System.spur-kfr.730 Ancestors: System-kfr.730, System.spur-kfr.729 System-kfr.730 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Make sure the menu icons are added if needed to Standard System Fonts menu ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008272.html Name: System.spur-nice.731 Ancestors: System-nice.731, System.spur-kfr.730 System-nice.731 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 A DummyStream may do nothing, but shall mimic the answer of a regular stream. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008273.html Name: System.spur-topa.733 Ancestors: System-topa.733, System.spur-nice.732 System-topa.733 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Make a preference to dis/enable the Object History. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008274.html Name: System.spur-topa.734 Ancestors: System-topa.734, System.spur-topa.733 System-topa.734 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 (typo) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008275.html Name: Collections.spur-tfel.624 Ancestors: Collections-tfel.624, Collections.spur-tfel.623 Collections-tfel.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008276.html Name: Collections.spur-mt.625 Ancestors: Collections-mt.625 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Speed-up #endsWith: for strings. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008277.html Name: Collections.spur-ul.627 Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008278.html Name: Collections.spur-mt.631 Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HtmlReadWriter: support for comments added, list of ignored tags added ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008279.html Name: Collections-ul.624 Ancestors: Collections-tfel.623 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008280.html Name: Collections-ul.624 Ancestors: Collections-tfel.623 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008281.html Name: Collections.spur-ul.624 Ancestors: Collections-ul.624, Collections.spur-tfel.623 Collections-ul.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008282.html Name: Collections.spur-mt.625 Ancestors: Collections-mt.625, Collections.spur-tfel.624 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Speed-up #endsWith: for strings. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008283.html Name: Collections.spur-mt.626 Ancestors: Collections-mt.626, Collections.spur-mt.625 Collections-mt.626 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008284.html Name: Collections.spur-ul.628 Ancestors: Collections-ul.628, Collections.spur-ul.627 Collections-ul.628 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.625. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008285.html Name: Collections.spur-mt.631 Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 HtmlReadWriter: support for comments added, list of ignored tags added ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008286.html Name: Collections.spur-ul.627 Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.262 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. ============================================= From Das.Linux at gmx.de Mon May 4 22:10:32 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon May 4 22:10:37 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <55266F84-3964-4C7F-91FA-AA447456F5FE@gmx.de> On 04.05.2015, at 20:24, Chris Muller wrote: > On Mon, May 4, 2015 at 1:13 PM, Eliot Miranda wrote: >> This breaks my image, dumping it into the emergency evaluator, I *think* >> because the new LetterMask, AlphaNumbericMask and DigitBit variables are not >> handledf correctly by the Spur bootstrap. Sigh. So for those of you using >> Spur please *don't* update until I've fixed the bootstrap. >> >> You know, by /not/ releasing, we are delaying because now I am fixing the >> bootstrap to keep up with development, instead of us having released, and >> being able to freely commit on Spur. We are now wasting cycles. At least I >> am. > > I was having a similar thought just today because I needed an > up-to-date Spur image and thought about asking whether you'd like > someone to set that up as an automatic job, then realized, we just > need to release. > > Which, we are. We are not "not releasing", we _are_ releasing, its > just taking a bit longer than expected because there are still some > bugs and loose ends (unrelated to Marcel's work) still needing tied > up. Maintaining the separate branch and the bootstrap is a hassle, > but it shouldn't be much longer. Just to mention: http://build.squeak.org/job/SqueakTrunk/ tells us that a) we have 15 tests failing. KernelTests.Numbers.LargePositiveIntegerTest.testReciprocalModulo Tests.Dependencies.PackageDependencyTest.testToolBuilder Tests.Compiler.DecompilerTests.testDecompilerInClassesSAtoSM Tests.Compiler.ClosureCompilerTest.testSourceRangeAccessForBlueBookInjectInto Tests.Compiler.DecompilerTests.testDecompilerInClassesFNtoFZ Tests.Compiler.DecompilerTests.testDecompilerInClassesLAtoLM Tests.Exceptions.ExceptionTests.testHandlerFromActio Tests.Dependencies.PackageDependencyTest.testNetwork Tests.Dependencies.PackageDependencyTest.testPreferenceBrowser Tests.Release.ReleaseTest.testNoObsoleteClasses ToolsTests.Browser.BrowserTest.testSelectClassNamedPreservesPlace MultilingualTests.Display.FontTest.testParagraph MultilingualTests.Display.FontTest.testParagraphFallback SqueakSSL.Tests.SqueakSSLTest.testYahooOpenID CollectionsTests.Text.TextAttributesScanningTest.testPluggableTextAttribute b) sometimes the current cog vm runs into a crash when executing TraitMethodDescriptionTest>>#testCategories (see http://build.squeak.org/job/SqueakTrunk/1413/console ) I'd rather have this to be the metric for the release? Best regards -Tobias From commits at source.squeak.org Mon May 4 22:25:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 22:25:46 2015 Subject: [squeak-dev] The Trunk: Tools-topa.620.mcz Message-ID: Tobias Pape uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-topa.620.mcz ==================== Summary ==================== Name: Tools-topa.620 Author: topa Time: 5 May 2015, 12:25:24.029 am UUID: 549e4118-d7f3-40de-a37d-38886dd9717d Ancestors: Tools-mt.619 Use a temporary instead of an ensure around a return. =============== Diff against Tools-mt.619 =============== Item was changed: ----- Method: ObjectExplorer>>buildWith: (in category 'toolbuilder') ----- buildWith: builder + | windowSpec treeSpec textSpec buttonSpec buttonOffset tool | - | windowSpec treeSpec textSpec buttonSpec buttonOffset | windowSpec := builder pluggableWindowSpec new. windowSpec model: self; children: OrderedCollection new; label: #label; extent: self initialExtent. treeSpec := builder pluggableTreeSpec new. treeSpec model: self; nodeClass: self class nodeClass; roots: #getList; keyPress: #explorerKey:from:event:; getSelected: #currentSelection; setSelected: #currentSelection:; setSelectedParent: #currentParent:; menu: #genericMenu:; autoDeselect: false; columns: (ObjectExplorerWrapper showContentsInColumns ifTrue: [{ [:listMorph | (listMorph filteredItems collect: [:item | item preferredWidthOfColumn: 1]) max]. nil "take all the space"}]); frame: (0@0 corner: 1@0.71). windowSpec children add: treeSpec. buttonOffset := (Preferences standardButtonFont widthOfString: 'inspect') * 3/2. textSpec := builder pluggableCodePaneSpec new. textSpec model: self; getText: #expression; editText: #expression:; menu: #codePaneMenu:shifted:; help: 'Evaluate expressions for the current tree selection...' translated; frame: (LayoutFrame fractions: (0@0.71 corner: 1@1) offsets: (0@0 corner: buttonOffset negated@0)). windowSpec children add: textSpec. buttonSpec := builder pluggableButtonSpec new model: self; label: 'inspect'; action: #inspectObject; help: 'Switch to an inspector tool'; frame: (LayoutFrame fractions: (1@0.71 corner: 1@1) offsets: (buttonOffset negated@0 corner: 0 @ 0)). windowSpec children add: buttonSpec. + + tool := builder build: windowSpec. + self changed: #expandRootsRequested. + ^ tool! - - [^ builder build: windowSpec] - ensure: [self changed: #expandRootsRequested]! From leves at elte.hu Mon May 4 22:41:10 2015 From: leves at elte.hu (Levente Uzonyi) Date: Mon May 4 22:41:14 2015 Subject: [squeak-dev] incorrect Shout rendering in ObjectExplorer In-Reply-To: References: Message-ID: Interesting. I wonder when has that changed. Anyway, Shout is not prepared for this scenario, so the API has to be changed a bit. Levente On Mon, 4 May 2015, Chris Muller wrote: > On Mon, May 4, 2015 at 3:56 PM, Levente Uzonyi wrote: >> In an Explorer you can't evaluate an expression in the context of an Object. >> That's what an Inspector is for. > > Huh? If I explore, say, Smalltalk, and select the "root" row of the > explorer, then I can evaluate any expressoins I want in the context of > the selected object, Smalltalk. > > Likewise, I can directly access the selected objects instVars. For > example, while the root is selected I can evaluate "globals class" and > it tells me its an Environment. > > The problem, whether I'm in an Explorer or an Inspector, is the new > Shout color rendering is rendering instVars in the color I've chosen > for "invalid" (in the Shout style table). > > See picture. I style my "invalid" code an ugly magenta, so it stands > out. But I don't want that when its not invalid, of course.. > From commits at source.squeak.org Mon May 4 22:55:15 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 22:55:16 2015 Subject: [squeak-dev] The Trunk: Monticello-eem.614.mcz Message-ID: Eliot Miranda uploaded a new version of Monticello to project The Trunk: http://source.squeak.org/trunk/Monticello-eem.614.mcz ==================== Summary ==================== Name: Monticello-eem.614 Author: eem Time: 4 May 2015, 3:54:59.534 pm UUID: 84864628-f241-44d1-929f-0016426c5dd3 Ancestors: Monticello-mt.613 Check for an empty log message before accepting a save. =============== Diff against Monticello-mt.613 =============== Item was changed: ----- Method: MCSaveVersionDialog>>accept (in category 'actions') ----- accept + | logMessage | self updateItems. + logMessage := (self findTextMorph: #logMessage) text asString. + (logMessage isEmpty or: [logMessage beginsWith: 'empty log message']) ifTrue: + [(UIManager confirm: 'the log message is empty; are you sure you want to commit') ifFalse: + [^self]]. self answer: (Array with: (self findTextMorph: #versionName) text asString + with: logMessage - with: (self findTextMorph: #logMessage) text asString with: ignore) ! From commits at source.squeak.org Mon May 4 23:07:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 23:07:40 2015 Subject: [squeak-dev] The Inbox: ShoutCore-ul.49.mcz Message-ID: A new version of ShoutCore was added to project The Inbox: http://source.squeak.org/inbox/ShoutCore-ul.49.mcz ==================== Summary ==================== Name: ShoutCore-ul.49 Author: ul Time: 5 May 2015, 1:06:58.433 am UUID: 965b17b5-211b-4841-903f-be90e72d003d Ancestors: ShoutCore-ul.48 Fix styling in Inspectors and ObjectExplorers. =============== Diff against ShoutCore-ul.48 =============== Item was added: + ----- Method: Inspector>>aboutToStyle: (in category '*ShoutCore') ----- + aboutToStyle: aStyler + + aStyler + classOrMetaClass: object class; + parseAMethod: false. + ^true! Item was added: + ----- Method: ObjectExplorer>>aboutToStyle: (in category '*ShoutCore') ----- + aboutToStyle: aStyler + + aStyler + classOrMetaClass: self object class; + parseAMethod: false. + ^true + ! Item was changed: Object subclass: #SHParserST80 + instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment allowUnderscoreAssignments allowUnderscoreSelectors parseAMethod' - instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment allowUnderscoreAssignments allowUnderscoreSelectors' classVariableNames: '' poolDictionaries: '' category: 'ShoutCore-Parsing'! !SHParserST80 commentStamp: 'tween 8/16/2004 15:44' prior: 0! I am a Smalltalk method / expression parser. Rather than creating an Abstract Syntax Tree, I create a sequence of SHRanges (in my 'ranges' instance variable), which represent the tokens within the String I am parsing. I am used by a SHTextStylerST80 to parse method source strings. I am able to parse incomplete / incorrect methods, and so can be used to parse methods that are being edited. My 'source' instance variable should be set to the string to be parsed. My 'classOrMetaClass' instance var must be set to the class or metaClass for the method source so that I can correctly resolve identifiers within the source. If this is nil , I parse the source as an expression (i.e. a doIt expression). My 'workspace' instance variable can be set to a Workspace, so that I can resolve workspace variables. My 'environment' instance variable is the global namespace (this is initialized to Smalltalk, but can be set to a different environment). Example 1. ranges := SHParserST80 new classOrMetaClass: Object; source: 'testMethod ^self'; parse; ranges ! Item was changed: ----- Method: SHParserST80>>parse (in category 'parse') ----- parse "Parse the receiver's text as a Smalltalk method" + self parse: (parseAMethod ifNil: [ classOrMetaClass notNil ]). - self parse: classOrMetaClass notNil. errorBlock := nil! Item was added: + ----- Method: SHParserST80>>parseAMethod: (in category 'accessing') ----- + parseAMethod: aBoolean + + parseAMethod := aBoolean! Item was changed: SHTextStyler subclass: #SHTextStylerST80 + instanceVariableNames: 'classOrMetaClass workspace font parser formatAssignments environment sourceMap processedSourceMap pixelHeight attributesByPixelHeight parseAMethod' - instanceVariableNames: 'classOrMetaClass workspace font parser formatAssignments environment sourceMap processedSourceMap pixelHeight attributesByPixelHeight' classVariableNames: 'SubduedSyntaxHighlights SyntaxHighlightingAsYouType SyntaxHighlightingAsYouTypeAnsiAssignment SyntaxHighlightingAsYouTypeLeftArrowAssignment' poolDictionaries: '' category: 'ShoutCore-Styling'! SHTextStylerST80 class instanceVariableNames: 'styleTable textAttributesByPixelHeight'! !SHTextStylerST80 commentStamp: 'tween 8/27/2004 10:55' prior: 0! I style Smalltalk methods and expressions. My 'styleTable' class instance var holds an array ofArrays which control how each token is styled/coloured. See my defaultStyleTable class method for its structure. My styleTable can be changed by either modifying the defaultStyleTable class method and then executing SHTextStylerST80 initialize ; or by giving me a new styleTable through my #styleTable: class method. My 'textAttributesByPixelSize' class instance var contains a dictionary of dictionaries. The key is a pixelSize and the value a Dictionary from token type Symbol to TextAttribute array. It is created/maintained automatically. I also install these 3 preferences when my class initialize method is executed.... #syntaxHighlightingAsYouType - controls whether methods are styled in browsers #syntaxHighlightingAsYouTypeAnsiAssignment - controls whether assignments are formatted to be := #syntaxHighlightingAsYouTypeLeftArrowAssignment - controls whether assignments are formatted to be _ I reimplement #unstyledTextFrom: so that TextActions are preserved in the unstyled text ! SHTextStylerST80 class instanceVariableNames: 'styleTable textAttributesByPixelHeight'! Item was added: + ----- Method: SHTextStylerST80>>parseAMethod: (in category 'accessing') ----- + parseAMethod: aBoolean + + parseAMethod := aBoolean! Item was changed: ----- Method: SHTextStylerST80>>rangesIn:setWorkspace: (in category 'private') ----- rangesIn: aText setWorkspace: aBoolean "Answer a collection of SHRanges by parsing aText. When formatting it is not necessary to set the workspace, and this can make the parse take less time, so aBoolean specifies whether the parser should be given the workspace" | shoutParserClass | "Switch parsers if we have to" shoutParserClass := (classOrMetaClass ifNil:[Object]) shoutParserClass. + parser class == shoutParserClass ifFalse:[parser := shoutParserClass new]. + parser parseAMethod: parseAMethod. - parser class = shoutParserClass ifFalse:[parser := shoutParserClass new]. - ^parser rangesIn: aText asString classOrMetaClass: classOrMetaClass workspace: (aBoolean ifTrue:[workspace]) environment: environment ! From commits at source.squeak.org Mon May 4 23:22:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 23:22:49 2015 Subject: [squeak-dev] The Trunk: Collections-ul.625.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.625.mcz ==================== Summary ==================== Name: Collections-ul.625 Author: ul Time: 1 May 2015, 1:41:40.726 pm UUID: d09538cd-53f4-42d7-8070-224fde4a4ae2 Ancestors: Collections-ul.624 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. =============== Diff against Collections-ul.624 =============== Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + value > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: value)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + value > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: value)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! From commits at source.squeak.org Mon May 4 23:23:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 4 23:23:05 2015 Subject: [squeak-dev] The Trunk: Collections-ul.624.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.624.mcz ==================== Summary ==================== Name: Collections-ul.624 Author: ul Time: 1 May 2015, 1:40:09.445 pm UUID: a89640e5-e0cc-44e1-9613-e065b78258ad Ancestors: Collections-tfel.623 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. =============== Diff against Collections-tfel.623 =============== Item was changed: Magnitude subclass: #Character instanceVariableNames: 'value' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + ClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + ClassificationTable at: code + 1 put: value ]! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + value < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | numArgs aStream offs |. - (numArgs := self numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From karlramberg at gmail.com Tue May 5 01:35:54 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 5 01:35:58 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: That must be a bug. Karl On Mon, May 4, 2015 at 11:27 PM, Chris Muller wrote: > On Mon, May 4, 2015 at 4:18 PM, Chris Muller wrote: > > One thing I don't like about the scattered preferences is how the > > preference API is no longer supported. I have a script which sets up > > my preferred preferences, I tried to write: > > > > Preferences disable: #showMessageIcons > > > > just like I can for "normal" preferences, however, the above doesn't > > work and doesn't report an error... > > In fact, it can even cause a duplicate preference to be added (see > picture). > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150505/95ba9f65/attachment.htm From eliot.miranda at gmail.com Tue May 5 01:52:16 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue May 5 01:52:19 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: <55266F84-3964-4C7F-91FA-AA447456F5FE@gmx.de> References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> <55266F84-3964-4C7F-91FA-AA447456F5FE@gmx.de> Message-ID: On Mon, May 4, 2015 at 3:10 PM, Tobias Pape wrote: > > On 04.05.2015, at 20:24, Chris Muller wrote: > > > On Mon, May 4, 2015 at 1:13 PM, Eliot Miranda > wrote: > >> This breaks my image, dumping it into the emergency evaluator, I *think* > >> because the new LetterMask, AlphaNumbericMask and DigitBit variables > are not > >> handledf correctly by the Spur bootstrap. Sigh. So for those of you > using > >> Spur please *don't* update until I've fixed the bootstrap. > >> > >> You know, by /not/ releasing, we are delaying because now I am fixing > the > >> bootstrap to keep up with development, instead of us having released, > and > >> being able to freely commit on Spur. We are now wasting cycles. At > least I > >> am. > > > > I was having a similar thought just today because I needed an > > up-to-date Spur image and thought about asking whether you'd like > > someone to set that up as an automatic job, then realized, we just > > need to release. > > > > Which, we are. We are not "not releasing", we _are_ releasing, its > > just taking a bit longer than expected because there are still some > > bugs and loose ends (unrelated to Marcel's work) still needing tied > > up. Maintaining the separate branch and the bootstrap is a hassle, > > but it shouldn't be much longer. > > Just to mention: http://build.squeak.org/job/SqueakTrunk/ tells us that > > a) we have 15 tests failing. > > KernelTests.Numbers.LargePositiveIntegerTest.testReciprocalModulo > Tests.Dependencies.PackageDependencyTest.testToolBuilder > Tests.Compiler.DecompilerTests.testDecompilerInClassesSAtoSM > > Tests.Compiler.ClosureCompilerTest.testSourceRangeAccessForBlueBookInjectInto > Tests.Compiler.DecompilerTests.testDecompilerInClassesFNtoFZ > Tests.Compiler.DecompilerTests.testDecompilerInClassesLAtoLM > Tests.Exceptions.ExceptionTests.testHandlerFromActio > Tests.Dependencies.PackageDependencyTest.testNetwork > Tests.Dependencies.PackageDependencyTest.testPreferenceBrowser > Tests.Release.ReleaseTest.testNoObsoleteClasses > ToolsTests.Browser.BrowserTest.testSelectClassNamedPreservesPlace > MultilingualTests.Display.FontTest.testParagraph > MultilingualTests.Display.FontTest.testParagraphFallback > SqueakSSL.Tests.SqueakSSLTest.testYahooOpenID > > CollectionsTests.Text.TextAttributesScanningTest.testPluggableTextAttribute > > > b) sometimes the current cog vm runs into a crash when executing > TraitMethodDescriptionTest>>#testCategories > (see http://build.squeak.org/job/SqueakTrunk/1413/console ) > > I'd rather have this to be the metric for the release? > and how can we get to zero defects if we keep on developing? > > Best regards > -Tobias -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150504/e2656829/attachment.htm From karlramberg at gmail.com Tue May 5 02:14:33 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 5 02:14:36 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: So you must access with Preferences disable: #'Browser>>showMessageIcons' Otherwise a new preference is added :-( Unrelated, in a ObjectExplorer you can't click to get a menu on all preferences because the ObjectExplorer show a abbreviated text: eg. #'CodeHolder>>useMultiWindowBrowser' will show in the ObjectExplorer as #'CodeHolder>>u...indowBrowser' Karl On Tue, May 5, 2015 at 3:35 AM, karl ramberg wrote: > That must be a bug. > > Karl > > On Mon, May 4, 2015 at 11:27 PM, Chris Muller wrote: > >> On Mon, May 4, 2015 at 4:18 PM, Chris Muller wrote: >> > One thing I don't like about the scattered preferences is how the >> > preference API is no longer supported. I have a script which sets up >> > my preferred preferences, I tried to write: >> > >> > Preferences disable: #showMessageIcons >> > >> > just like I can for "normal" preferences, however, the above doesn't >> > work and doesn't report an error... >> >> In fact, it can even cause a duplicate preference to be added (see >> picture). >> >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150505/3a88cb3e/attachment.htm From karlramberg at gmail.com Tue May 5 08:20:31 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 5 08:20:35 2015 Subject: [squeak-dev] Re: Changing button groups/order in browsers In-Reply-To: References: <1430659768347-4823991.post@n4.nabble.com> <1430743283559-4824268.post@n4.nabble.com> Message-ID: Oh, I was not aware of these possibilities. It seem very powerful, but I must say I'm a little lost since I really don't know how to phrase these searches. There is so much to learn :-) Karl On Mon, May 4, 2015 at 8:00 PM, Chris Muller wrote: > On Mon, May 4, 2015 at 9:28 AM, karl ramberg > wrote: > > I was wondering about the senders and implementors buttons. It would be > nice > > to be able to chose either local or global scope. I'm not sure we have a > > nice button widget that can do that. > > Currently those buttons open a list of implementors with one click but > which can be subsequently filtered via "filter message list..." | > "messages that...". Then, in the dialog, simply enter the expression > how you want to filter. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150505/8d1985f4/attachment.htm From Marcel.Taeumel at hpi.de Tue May 5 08:54:16 2015 From: Marcel.Taeumel at hpi.de (Taeumel, Marcel) Date: Tue May 5 08:54:20 2015 Subject: AW: [squeak-dev] Re: Changing button groups/order in browsers In-Reply-To: References: <1430659768347-4823991.post@n4.nabble.com> <1430743283559-4824268.post@n4.nabble.com> Message-ID: There may be room for improving the usability here. ;-) Best, Marcel Von: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] Im Auftrag von karl ramberg Gesendet: Dienstag, 5. Mai 2015 10:21 An: Chris Muller; The general-purpose Squeak developers list Betreff: Re: [squeak-dev] Re: Changing button groups/order in browsers Oh, I was not aware of these possibilities. It seem very powerful, but I must say I'm a little lost since I really don't know how to phrase these searches. There is so much to learn :-) Karl On Mon, May 4, 2015 at 8:00 PM, Chris Muller > wrote: On Mon, May 4, 2015 at 9:28 AM, karl ramberg > wrote: > I was wondering about the senders and implementors buttons. It would be nice > to be able to chose either local or global scope. I'm not sure we have a > nice button widget that can do that. Currently those buttons open a list of implementors with one click but which can be subsequently filtered via "filter message list..." | "messages that...". Then, in the dialog, simply enter the expression how you want to filter. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150505/246c6282/attachment.htm From leves at elte.hu Tue May 5 10:27:54 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 5 10:27:59 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: It seems to me that the tool which creates the .spur versions of the packages is running in an updated non-spur Trunk image, and it somehow added its own version of #isAlphaNumeric to Collections.spur-tfel.623. The method in Collections.spur-tfel.623 is: isAlphaNumeric "Answer whether the receiver is a letter or a digit." self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self While in Collections-tfel.623 it is: isAlphaNumeric "Answer whether the receiver is a letter or a digit." ^self encodedCharSet isAlphaNumeric: self The version which got patched is from Collections-ul.628 (which merges Collections-ul.625): isAlphaNumeric "Answer whether the receiver is a letter or a digit." value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self If I'm right, then we can work around the problem by updating the current methods in Trunk to check whether the AlphaNumericMask is initialized (along with DigitBit and LetterMask). Then update the image which creates, the .spur versions, and finally recreate the Collections.spur packages starting from tfel-623. Levente On Mon, 4 May 2015, Eliot Miranda wrote: > > > On Mon, May 4, 2015 at 1:55 PM, Levente Uzonyi wrote: > I tried to update an old Spur image, and somehow Character >> #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by > update.spur-ul.311) appeared in the image, while loading Collections.spur-tfel.623 from update.spur-mt.310. > Assuming that the load order of the packages is untouched, I suspect that the method got merged in from the non-spur branch of > Collections somehow. > > > I think the multiple ancestry that one ends up with in Spur packages, e.g. that Collections.spur-abc.123 inherits from > both?Collections.spur-xyz-122 and?Collections.abc-123, causes issues for the update merge.? I wonder whether that could be the cause? From Marcel.Taeumel at hpi.de Tue May 5 11:32:57 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 5 11:48:37 2015 Subject: [squeak-dev] Re: The Inbox: ShoutCore-ul.49.mcz In-Reply-To: References: Message-ID: <1430825577454-4824538.post@n4.nabble.com> This shouldn't be an extension to ShoutCore but a regular implementation of #aboutToStyle: in Inspector and ObjectExplorer. Shout will check for that. All other tools do it that way. The Tools package should be no dependency for loading ShoutCore. Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-ShoutCore-ul-49-mcz-tp4824458p4824538.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 5 11:36:12 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 5 11:51:51 2015 Subject: [squeak-dev] Re: incorrect Shout rendering in ObjectExplorer In-Reply-To: References: Message-ID: <1430825772715-4824540.post@n4.nabble.com> Of course, Shout is prepared for that. It calls #aboutToStyle: in all other tools out there to update its internal state. :) Best, Marcel -- View this message in context: http://forum.world.st/incorrect-Shout-rendering-in-ObjectExplorer-tp4824413p4824540.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Tue May 5 12:38:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 12:38:01 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Morphic-mt.145.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.145.mcz ==================== Summary ==================== Name: ToolBuilder-Morphic-mt.145 Author: mt Time: 5 May 2015, 2:37:52.882 pm UUID: 7beaed04-a52a-b843-ab62-1351a8d79d97 Ancestors: ToolBuilder-Morphic-mt.144 Give models/tools the chance to restyle dependent widgets (text fields) if needed. =============== Diff against ToolBuilder-Morphic-mt.144 =============== Item was changed: ----- Method: PluggableTextMorphPlus>>hasUnacceptedEdits: (in category 'styling') ----- hasUnacceptedEdits: aBoolean "re-implemented to re-style the text iff aBoolean is true" super hasUnacceptedEdits: aBoolean. + aBoolean ifTrue: [ self updateStyle ].! - (aBoolean and: [self okToStyle]) - ifTrue: [ styler styleInBackgroundProcess: textMorph contents]! Item was changed: ----- Method: PluggableTextMorphPlus>>update: (in category 'updating') ----- update: what what ifNil:[^self]. what == getColorSelector ifTrue:[self color: (model perform: getColorSelector)]. + what == #styleChanged ifTrue: [self updateStyle]. + ^super update: what! Item was added: + ----- Method: PluggableTextMorphPlus>>updateStyle (in category 'styling') ----- + updateStyle + + self okToStyle + ifTrue: [styler styleInBackgroundProcess: textMorph contents].! From Marcel.Taeumel at hpi.de Tue May 5 12:23:38 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 5 12:39:18 2015 Subject: [squeak-dev] Re: incorrect Shout rendering in ObjectExplorer In-Reply-To: <1430825772715-4824540.post@n4.nabble.com> References: <1430825772715-4824540.post@n4.nabble.com> Message-ID: <1430828618969-4824575.post@n4.nabble.com> Ah, now I know, what you meant. I added this: http://forum.world.st/The-Trunk-ToolBuilder-Morphic-mt-145-mcz-td4824574.html Now you can send "self changed: #styleChanged" to let text morphs restyle. Best, Marcel -- View this message in context: http://forum.world.st/incorrect-Shout-rendering-in-ObjectExplorer-tp4824413p4824575.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Tue May 5 12:47:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 12:47:30 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Morphic-mt.146.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.146.mcz ==================== Summary ==================== Name: ToolBuilder-Morphic-mt.146 Author: mt Time: 5 May 2015, 2:47:21.358 pm UUID: 43c4e6d4-a91f-b54a-bf6f-650cd06642ec Ancestors: ToolBuilder-Morphic-mt.145 Spelling improved for last commit about re-styling in text morphs. =============== Diff against ToolBuilder-Morphic-mt.145 =============== Item was changed: ----- Method: PluggableTextMorphPlus>>update: (in category 'updating') ----- update: what what ifNil:[^self]. what == getColorSelector ifTrue:[self color: (model perform: getColorSelector)]. + what == #style ifTrue: [self updateStyle]. - what == #styleChanged ifTrue: [self updateStyle]. ^super update: what! From karlramberg at gmail.com Tue May 5 12:54:33 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 5 12:54:37 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-kfr.958.mcz In-Reply-To: References: <1430590097489-4823795.post@n4.nabble.com> <1430634471479-4823901.post@n4.nabble.com> <1430635707869-4823904.post@n4.nabble.com> <1430646993279-4823948.post@n4.nabble.com> Message-ID: Preferences>>enable: and Preferences>>disable: considered harmful. Both methods have side effects that are not desirable. The naming scheme of PragmaPreferences and old Preferences do not match. PragmaPreference key #'Browser>>showMessageIcons' Preference key #alwaysHideHScrollbar Both methods enable: and disable: automatically create a new preference in the dictionary if the key searched for is not found. This can easily lead to duplicate entries in the DictionaryOfPreferences. Karl On Tue, May 5, 2015 at 4:14 AM, karl ramberg wrote: > So you must access with > Preferences disable: #'Browser>>showMessageIcons' > > Otherwise a new preference is added :-( > > Unrelated, in a ObjectExplorer you can't click to get a menu on all > preferences because the ObjectExplorer show a abbreviated text: eg. > #'CodeHolder>>useMultiWindowBrowser' will show in the ObjectExplorer as > #'CodeHolder>>u...indowBrowser' > > Karl > > On Tue, May 5, 2015 at 3:35 AM, karl ramberg > wrote: > >> That must be a bug. >> >> Karl >> >> On Mon, May 4, 2015 at 11:27 PM, Chris Muller >> wrote: >> >>> On Mon, May 4, 2015 at 4:18 PM, Chris Muller >>> wrote: >>> > One thing I don't like about the scattered preferences is how the >>> > preference API is no longer supported. I have a script which sets up >>> > my preferred preferences, I tried to write: >>> > >>> > Preferences disable: #showMessageIcons >>> > >>> > just like I can for "normal" preferences, however, the above doesn't >>> > work and doesn't report an error... >>> >>> In fact, it can even cause a duplicate preference to be added (see >>> picture). >>> >>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150505/cec9e17b/attachment-0001.htm From commits at source.squeak.org Tue May 5 13:19:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 13:19:34 2015 Subject: [squeak-dev] The Trunk: ShoutCore-ul.49.mcz Message-ID: Marcel Taeumel uploaded a new version of ShoutCore to project The Trunk: http://source.squeak.org/trunk/ShoutCore-ul.49.mcz ==================== Summary ==================== Name: ShoutCore-ul.49 Author: ul Time: 5 May 2015, 1:06:58.433 am UUID: 965b17b5-211b-4841-903f-be90e72d003d Ancestors: ShoutCore-ul.48 Fix styling in Inspectors and ObjectExplorers. =============== Diff against ShoutCore-ul.48 =============== Item was added: + ----- Method: Inspector>>aboutToStyle: (in category '*ShoutCore') ----- + aboutToStyle: aStyler + + aStyler + classOrMetaClass: object class; + parseAMethod: false. + ^true! Item was added: + ----- Method: ObjectExplorer>>aboutToStyle: (in category '*ShoutCore') ----- + aboutToStyle: aStyler + + aStyler + classOrMetaClass: self object class; + parseAMethod: false. + ^true + ! Item was changed: Object subclass: #SHParserST80 + instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment allowUnderscoreAssignments allowUnderscoreSelectors parseAMethod' - instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment allowUnderscoreAssignments allowUnderscoreSelectors' classVariableNames: '' poolDictionaries: '' category: 'ShoutCore-Parsing'! !SHParserST80 commentStamp: 'tween 8/16/2004 15:44' prior: 0! I am a Smalltalk method / expression parser. Rather than creating an Abstract Syntax Tree, I create a sequence of SHRanges (in my 'ranges' instance variable), which represent the tokens within the String I am parsing. I am used by a SHTextStylerST80 to parse method source strings. I am able to parse incomplete / incorrect methods, and so can be used to parse methods that are being edited. My 'source' instance variable should be set to the string to be parsed. My 'classOrMetaClass' instance var must be set to the class or metaClass for the method source so that I can correctly resolve identifiers within the source. If this is nil , I parse the source as an expression (i.e. a doIt expression). My 'workspace' instance variable can be set to a Workspace, so that I can resolve workspace variables. My 'environment' instance variable is the global namespace (this is initialized to Smalltalk, but can be set to a different environment). Example 1. ranges := SHParserST80 new classOrMetaClass: Object; source: 'testMethod ^self'; parse; ranges ! Item was changed: ----- Method: SHParserST80>>parse (in category 'parse') ----- parse "Parse the receiver's text as a Smalltalk method" + self parse: (parseAMethod ifNil: [ classOrMetaClass notNil ]). - self parse: classOrMetaClass notNil. errorBlock := nil! Item was added: + ----- Method: SHParserST80>>parseAMethod: (in category 'accessing') ----- + parseAMethod: aBoolean + + parseAMethod := aBoolean! Item was changed: SHTextStyler subclass: #SHTextStylerST80 + instanceVariableNames: 'classOrMetaClass workspace font parser formatAssignments environment sourceMap processedSourceMap pixelHeight attributesByPixelHeight parseAMethod' - instanceVariableNames: 'classOrMetaClass workspace font parser formatAssignments environment sourceMap processedSourceMap pixelHeight attributesByPixelHeight' classVariableNames: 'SubduedSyntaxHighlights SyntaxHighlightingAsYouType SyntaxHighlightingAsYouTypeAnsiAssignment SyntaxHighlightingAsYouTypeLeftArrowAssignment' poolDictionaries: '' category: 'ShoutCore-Styling'! SHTextStylerST80 class instanceVariableNames: 'styleTable textAttributesByPixelHeight'! !SHTextStylerST80 commentStamp: 'tween 8/27/2004 10:55' prior: 0! I style Smalltalk methods and expressions. My 'styleTable' class instance var holds an array ofArrays which control how each token is styled/coloured. See my defaultStyleTable class method for its structure. My styleTable can be changed by either modifying the defaultStyleTable class method and then executing SHTextStylerST80 initialize ; or by giving me a new styleTable through my #styleTable: class method. My 'textAttributesByPixelSize' class instance var contains a dictionary of dictionaries. The key is a pixelSize and the value a Dictionary from token type Symbol to TextAttribute array. It is created/maintained automatically. I also install these 3 preferences when my class initialize method is executed.... #syntaxHighlightingAsYouType - controls whether methods are styled in browsers #syntaxHighlightingAsYouTypeAnsiAssignment - controls whether assignments are formatted to be := #syntaxHighlightingAsYouTypeLeftArrowAssignment - controls whether assignments are formatted to be _ I reimplement #unstyledTextFrom: so that TextActions are preserved in the unstyled text ! SHTextStylerST80 class instanceVariableNames: 'styleTable textAttributesByPixelHeight'! Item was added: + ----- Method: SHTextStylerST80>>parseAMethod: (in category 'accessing') ----- + parseAMethod: aBoolean + + parseAMethod := aBoolean! Item was changed: ----- Method: SHTextStylerST80>>rangesIn:setWorkspace: (in category 'private') ----- rangesIn: aText setWorkspace: aBoolean "Answer a collection of SHRanges by parsing aText. When formatting it is not necessary to set the workspace, and this can make the parse take less time, so aBoolean specifies whether the parser should be given the workspace" | shoutParserClass | "Switch parsers if we have to" shoutParserClass := (classOrMetaClass ifNil:[Object]) shoutParserClass. + parser class == shoutParserClass ifFalse:[parser := shoutParserClass new]. + parser parseAMethod: parseAMethod. - parser class = shoutParserClass ifFalse:[parser := shoutParserClass new]. - ^parser rangesIn: aText asString classOrMetaClass: classOrMetaClass workspace: (aBoolean ifTrue:[workspace]) environment: environment ! From commits at source.squeak.org Tue May 5 13:20:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 13:20:59 2015 Subject: [squeak-dev] The Trunk: ShoutCore-mt.50.mcz Message-ID: Marcel Taeumel uploaded a new version of ShoutCore to project The Trunk: http://source.squeak.org/trunk/ShoutCore-mt.50.mcz ==================== Summary ==================== Name: ShoutCore-mt.50 Author: mt Time: 5 May 2015, 3:20:52.67 pm UUID: e50593ae-daab-8b42-8127-73547490fcdd Ancestors: ShoutCore-ul.49 Remove Tools dependency. =============== Diff against ShoutCore-ul.49 =============== Item was removed: - ----- Method: Inspector>>aboutToStyle: (in category '*ShoutCore') ----- - aboutToStyle: aStyler - - aStyler - classOrMetaClass: object class; - parseAMethod: false. - ^true! Item was removed: - ----- Method: ObjectExplorer>>aboutToStyle: (in category '*ShoutCore') ----- - aboutToStyle: aStyler - - aStyler - classOrMetaClass: self object class; - parseAMethod: false. - ^true - ! From leves at elte.hu Tue May 5 13:22:21 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 5 13:22:27 2015 Subject: [squeak-dev] Re: Using Artefact PDF library in Squeak In-Reply-To: References: <5544fd9d.619b340a.67a2.ffffadd8SMTPIN_ADDED_MISSING@mx.google.com> <0EE454FD-FF87-4E81-8305-EF75BDCDB07E@gmail.com> Message-ID: On Mon, 4 May 2015, Stephan Eggermont wrote: > On 02/05/15 21:40, Levente Uzonyi wrote: >> >> I remember #asDictionary now. This is what happens when you don't want >> caseOf: and caseOf:otherwise: be in your language: >> >> ^PDFDataSymbol symbol: ({ #singlePage->'SinglePage' . >> #continuousPages->'OneColumn' . #twoPages->'TwoColumnLeft' } >> asDictionary at: self displayLayout). > > That is ugly, I concur. What concrete action do you propose? I've rewritten these to #caseOf: statements in my Squeak port[1]. Levente [1] http://leves.web.elte.hu/squeak/Artefact/ > > Stephan > > > > > From commits at source.squeak.org Tue May 5 13:25:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 13:25:52 2015 Subject: [squeak-dev] The Trunk: Tools-mt.621.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.621.mcz ==================== Summary ==================== Name: Tools-mt.621 Author: mt Time: 5 May 2015, 3:25:28.303 pm UUID: 8f0550eb-835e-cd45-986d-16324d4fdad5 Ancestors: Tools-topa.620 Fixes styling in Inspector and Object Explorer. Thanks to Levente for the idea of #parseAMethod: in Shout styler. :-) =============== Diff against Tools-topa.620 =============== Item was added: + ----- Method: Inspector>>aboutToStyle: (in category 'styling') ----- + aboutToStyle: aStyler + + aStyler + classOrMetaClass: object class; + parseAMethod: false. + ^true! Item was added: + ----- Method: ObjectExplorer>>aboutToStyle: (in category 'styling') ----- + aboutToStyle: aStyler + + aStyler + classOrMetaClass: self object class; + parseAMethod: false. + ^true + ! Item was changed: ----- Method: ObjectExplorer>>currentSelection: (in category 'accessing') ----- currentSelection: anObject self currentSelection == anObject ifTrue: [^ self]. currentSelection := anObject. + + self changed: #currentSelection. + self changed: #style.! - self changed: #currentSelection.! From Marcel.Taeumel at hpi.de Tue May 5 13:11:38 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 5 13:27:18 2015 Subject: [squeak-dev] Re: incorrect Shout rendering in ObjectExplorer In-Reply-To: References: Message-ID: <1430831498739-4824604.post@n4.nabble.com> Works now: http://forum.world.st/The-Trunk-Tools-mt-621-mcz-td4824603.html Best, Marcel -- View this message in context: http://forum.world.st/incorrect-Shout-rendering-in-ObjectExplorer-tp4824413p4824604.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From leves at elte.hu Tue May 5 13:47:34 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 5 13:47:38 2015 Subject: [squeak-dev] Re: The Inbox: ShoutCore-ul.49.mcz In-Reply-To: <1430825577454-4824538.post@n4.nabble.com> References: <1430825577454-4824538.post@n4.nabble.com> Message-ID: Well, the same can be done to the Monticello package too. Levente On Tue, 5 May 2015, marcel.taeumel wrote: > This shouldn't be an extension to ShoutCore but a regular implementation of > #aboutToStyle: in Inspector and ObjectExplorer. > > Shout will check for that. All other tools do it that way. > > The Tools package should be no dependency for loading ShoutCore. > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Inbox-ShoutCore-ul-49-mcz-tp4824458p4824538.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From Marcel.Taeumel at hpi.de Tue May 5 13:44:31 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 5 14:00:12 2015 Subject: [squeak-dev] Re: The Inbox: ShoutCore-ul.49.mcz In-Reply-To: References: <1430825577454-4824538.post@n4.nabble.com> Message-ID: <1430833471097-4824618.post@n4.nabble.com> Absolutely. We might miss an abstraction between ShoutCore and Tools right now but that's how it is right now. Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-ShoutCore-ul-49-mcz-tp4824458p4824618.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Tue May 5 14:18:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 14:18:11 2015 Subject: [squeak-dev] The Trunk: ReleaseBuilder-kfr.121.mcz Message-ID: Karl Ramberg uploaded a new version of ReleaseBuilder to project The Trunk: http://source.squeak.org/trunk/ReleaseBuilder-kfr.121.mcz ==================== Summary ==================== Name: ReleaseBuilder-kfr.121 Author: kfr Time: 5 May 2015, 4:17:58.006 pm UUID: e6126cb9-b0ff-ea45-8ebc-92a434ef0312 Ancestors: ReleaseBuilder-mt.120 Changes to use SystemNavigation thoroughSenders: true =============== Diff against ReleaseBuilder-mt.120 =============== Item was changed: ----- Method: ReleaseBuilder class>>setPreferences45 (in category 'preferences') ----- setPreferences45 self setProjectBackground: self projectBackground45. Workspace shouldStyle: false. SystemWindow reuseWindows: true. TextEditor autoEnclose: true ; autoIndent: false ; destructiveBackWord: false ; blinkingCursor: false ; dumbbellCursor: false. BalloonMorph setBalloonColorTo: (TranslucentColor r: 0.92 g: 0.92 b: 0.706 alpha: 0.75). Preferences installBrightWindowColors ; insertionPointColor: Color red ; enable: #scrollBarsWithoutMenuButton ; enable: #gradientScrollBars ; enable: #swapMouseButtons ; enable: #annotationPanes ; disable: #showSplitterHandles ; enable: #showBoundsInHalo ; disable: #alternateHandlesLook ; disable: #roundedMenuCorners ; disable: #roundedWindowCorners ; enable: #traceMessages ; - enable: #thoroughSenders ; enable: #diffsWithPrettyPrint ; disable: #alwaysShowVScrollbar ; enable: #alternativeBrowseIt. ProportionalSplitterMorph smartHorizontalSplitters: false ; smartVerticalSplitters: false. PluggableButtonMorph roundedButtonCorners: false. FillInTheBlankMorph roundedDialogCorners: false. Workspace shouldStyle: false. NetNameResolver enableIPv6: false. + Browser listClassesHierarchically: true. + SystemNavigation thoroughSenders: true! - Browser listClassesHierarchically: true! Item was changed: ----- Method: ReleaseBuilder class>>setPreferences46 (in category 'preferences') ----- setPreferences46 "Preferences class defaultValueTableForCurrentRelease" self setProjectBackground: self projectBackground46. "General User interaction" Preferences disable: #swapMouseButtons; enable: #mouseOverForKeyboardFocus. Morph indicateKeyboardFocus: true. "Text input." TextEditor autoEnclose: false ; autoIndent: true ; destructiveBackWord: false ; blinkingCursor: true ; dumbbellCursor: false. Preferences insertionPointColor: Color red. PluggableTextMorph simpleFrameAdornments: false. "Windows" Preferences installNormalWindowColors. SystemWindow reuseWindows: false. Model windowActiveOnFirstClick: false. "Not good for 800x600" Preferences disable: #showSplitterHandles. CornerGripMorph drawCornerResizeHandles: false. ProportionalSplitterMorph smartHorizontalSplitters: false ; smartVerticalSplitters: false. "Scroll bars." Preferences enable: #scrollBarsNarrow; enable: #scrollBarsOnRight; disable: #alwaysHideHScrollbar; disable: #alwaysShowHScrollbar; disable: #alwaysShowVScrollbar. ScrollBar scrollBarsWithoutArrowButtons: true; scrollBarsWithoutMenuButton: true. ScrollPane useRetractableScrollBars: false. "Rounded corners." Morph preferredCornerRadius: 6. Preferences disable: #roundedWindowCorners. PluggableButtonMorph roundedButtonCorners: false. FillInTheBlankMorph roundedDialogCorners: false. MenuMorph roundedMenuCorners: false. ScrollBar roundedScrollBarLook: false. "Gradients." Preferences disable: #gradientScrollBars. SystemWindow gradientWindow: false. MenuMorph gradientMenu: false. PluggableButtonMorph gradientButton: false. "Shadows" Preferences enable: #menuAppearance3d. Morph useSoftDropShadow: true. "Lists and Trees" PluggableListMorph filterableLists: true; clearFilterAutomatically: false; highlightHoveredRow: true; menuRequestUpdatesSelection: true. PluggableTreeMorph filterByLabelsOnly: false; maximumSearchDepth: 1. LazyListMorph listSelectionTextColor: Color black; listSelectionColor: (Color r: 0.72 g: 0.72 b: 0.9). "Standard Tools" BalloonMorph setBalloonColorTo: (TranslucentColor r: 0.92 g: 0.92 b: 0.706 alpha: 0.75). Workspace shouldStyle: false. Browser listClassesHierarchically: true; showClassIcons: true; showMessageIcons: true; sortMessageCategoriesAlphabetically: true. Preferences enable: #annotationPanes; enable: #optionalButtons; enable: #diffsWithPrettyPrint; enable: #traceMessages ; - enable: #thoroughSenders ; enable: #alternativeBrowseIt; enable: #menuWithIcons; enable: #visualExplorer. + SystemNavigation thoroughSenders: true. + - "Halo" Preferences enable: #showBoundsInHalo ; disable: #alternateHandlesLook. "Network" NetNameResolver enableIPv6: false. + + ! - ! From commits at source.squeak.org Tue May 5 14:21:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 14:21:56 2015 Subject: [squeak-dev] The Trunk: System-kfr.735.mcz Message-ID: Karl Ramberg uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-kfr.735.mcz ==================== Summary ==================== Name: System-kfr.735 Author: kfr Time: 5 May 2015, 4:21:01.607 pm UUID: 6facccb7-8706-c243-a18d-f94b87f4513e Ancestors: System-topa.734 Changes to use SystemNavigation thoroughSenders: true =============== Diff against System-topa.734 =============== Item was changed: ----- Method: Preferences class>>defaultValueTableForCurrentRelease (in category 'misc') ----- defaultValueTableForCurrentRelease "Answer a table defining default values for all the preferences in the release. Returns a list of (pref-symbol, boolean-symbol) pairs" ^ #( (abbreviatedBrowserButtons false) (alternativeBrowseIt false) (annotationPanes false) (areaFillsAreTolerant false) (areaFillsAreVeryTolerant false) (automaticFlapLayout true) (automaticKeyGeneration false) (automaticPlatformSettings true) (automaticViewerPlacement true) (balloonHelpEnabled true) (balloonHelpInMessageLists false) (batchPenTrails false) (canRecordWhilePlaying false) (capitalizedReferences true) (caseSensitiveFinds false) (cautionBeforeClosing false) (changeSetVersionNumbers true) (checkForSlips true) (checkForUnsavedProjects true) (classicNavigatorEnabled false) (clickOnLabelToEdit false) (cmdDotEnabled true) (collapseWindowsInPlace false) (compactViewerFlaps false) (compressFlashImages false) (confirmFirstUseOfStyle true) (conversionMethodsAtFileOut false) (debugHaloHandle true) (debugPrintSpaceLog false) (debugShowDamage false) (decorateBrowserButtons true) (diffsInChangeList true) (diffsWithPrettyPrint false) (dismissAllOnOptionClose false) (dragNDropWithAnimation false) (eToyFriendly false) (eToyLoginEnabled false) (enableLocalSave true) (extractFlashInHighQuality true) (extractFlashInHighestQuality false) (fastDragWindowForMorphic true) (fenceEnabled true) (fullScreenLeavesDeskMargins true) (haloTransitions false) (hiddenScrollBars false) (higherPerformance false) (honorDesktopCmdKeys true) (ignoreStyleIfOnlyBold true) (includeSoundControlInNavigator false) (infiniteUndo false) (logDebuggerStackToFile true) (magicHalos false) (menuButtonInToolPane false) (menuColorFromWorld false) (menuKeyboardControl false) (modalColorPickers true) (mouseOverForKeyboardFocus false) (mouseOverHalos false) (mvcProjectsAllowed true) (navigatorOnLeftEdge true) (noviceMode false) (okToReinitializeFlaps true) (optionalButtons true) (passwordsOnPublish false) (personalizedWorldMenu true) (postscriptStoredAsEPS false) (projectViewsInWindows true) (projectZoom true) (projectsSentToDisk false) (propertySheetFromHalo false) (readDocumentAtStartup true) (restartAlsoProceeds false) (reverseWindowStagger true) (roundedMenuCorners true) (roundedWindowCorners true) (scrollBarsNarrow false) (scrollBarsOnRight true) (scrollBarsWithoutMenuButton false) (gradientScrollBars true) (securityChecksEnabled false) (selectiveHalos false) (showBoundsInHalo false) (showDirectionForSketches false) (showDirectionHandles false) (showFlapsWhenPublishing false) (showProjectNavigator false) (showSecurityStatus true) (showSharedFlaps true) (signProjectFiles true) (simpleMenus false) (smartUpdating true) (soundQuickStart false) (stopSoundWhenDone false) (soundEnabled true) (startInUntrustedDirectory false) (systemWindowEmbedOK false) - (thoroughSenders true) (tileTranslucentDrag true) (timeStampsInMenuTitles true) (turnOffPowerManager false) (twentyFourHourFileStamps true) (typeCheckingInTileScripting true) (uniTilesClassic true) (uniqueNamesInHalos false) (universalTiles false) (unlimitedPaintArea false) (useButtonProprtiesToFire false) (useUndo true) (viewersInFlaps true) (warnAboutInsecureContent true) (warnIfNoChangesFile true) (warnIfNoSourcesFile true)) " Preferences defaultValueTableForCurrentRelease do: [:pair | (Preferences preferenceAt: pair first ifAbsent: [nil]) ifNotNilDo: [:pref | pref defaultValue: (pair last == true)]]. Preferences chooseInitialSettings. "! Item was changed: ----- Method: Preferences class>>outOfTheBox (in category 'themes') ----- outOfTheBox "The default out-of-the-box preference settings for Squeak 3.2. The 'alternative' window-look and scrollbar-look are used. Button panes are used but not annotation panes. Scrollbars are on the right and do not flop out." + self setPreferencesFrom: self defaultValueTableForCurrentRelease. + SystemNavigation thoroughSenders: true! - self setPreferencesFrom: self defaultValueTableForCurrentRelease! From ma.chris.m at gmail.com Tue May 5 15:08:51 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Tue May 5 15:08:53 2015 Subject: [squeak-dev] Re: Changing button groups/order in browsers In-Reply-To: References: <1430659768347-4823991.post@n4.nabble.com> <1430743283559-4824268.post@n4.nabble.com> Message-ID: On Tue, May 5, 2015 at 3:20 AM, karl ramberg wrote: > Oh, I was not aware of these possibilities. > It seem very powerful, but I must say I'm a little lost since I really don't > know how to phrase these searches. So for that local-scope filter you mentioned, say you wanted to filter implementors which are local to the Collection hierarchy, so it would be the ones which #inheritsFrom: Collection. [:aClass :aSelector | aClass inheritsFrom: Collection ] #inheritsFrom: seems to be the one I use most often from that "messages that..." function. > There is so much to learn :-) After using Squeak for so long, I also get amazed sometimes when I discover old things that have been there for a long time which I didn't know.. :) From asqueaker at gmail.com Tue May 5 15:15:46 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 5 15:15:50 2015 Subject: [squeak-dev] The Trunk: ShoutCore-ul.49.mcz In-Reply-To: <5548c36b.e3a1340a.7208.525fSMTPIN_ADDED_MISSING@mx.google.com> References: <5548c36b.e3a1340a.7208.525fSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Thanks guys! On Tue, May 5, 2015 at 8:19 AM, wrote: > Marcel Taeumel uploaded a new version of ShoutCore to project The Trunk: > http://source.squeak.org/trunk/ShoutCore-ul.49.mcz > > ==================== Summary ==================== > > Name: ShoutCore-ul.49 > Author: ul > Time: 5 May 2015, 1:06:58.433 am > UUID: 965b17b5-211b-4841-903f-be90e72d003d > Ancestors: ShoutCore-ul.48 > > Fix styling in Inspectors and ObjectExplorers. > > =============== Diff against ShoutCore-ul.48 =============== > > Item was added: > + ----- Method: Inspector>>aboutToStyle: (in category '*ShoutCore') ----- > + aboutToStyle: aStyler > + > + aStyler > + classOrMetaClass: object class; > + parseAMethod: false. > + ^true! > > Item was added: > + ----- Method: ObjectExplorer>>aboutToStyle: (in category '*ShoutCore') ----- > + aboutToStyle: aStyler > + > + aStyler > + classOrMetaClass: self object class; > + parseAMethod: false. > + ^true > + ! > > Item was changed: > Object subclass: #SHParserST80 > + instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment allowUnderscoreAssignments allowUnderscoreSelectors parseAMethod' > - instanceVariableNames: 'classOrMetaClass source workspace arguments sourcePosition currentToken currentTokenFirst temporaries instanceVariables errorBlock currentTokenSourcePosition blockDepth bracketDepth ranges environment allowUnderscoreAssignments allowUnderscoreSelectors' > classVariableNames: '' > poolDictionaries: '' > category: 'ShoutCore-Parsing'! > > !SHParserST80 commentStamp: 'tween 8/16/2004 15:44' prior: 0! > I am a Smalltalk method / expression parser. > > Rather than creating an Abstract Syntax Tree, I create a sequence of SHRanges (in my 'ranges' instance variable), which represent the tokens within the String I am parsing. > > I am used by a SHTextStylerST80 to parse method source strings. > I am able to parse incomplete / incorrect methods, and so can be used to parse methods that are being edited. > > My 'source' instance variable should be set to the string to be parsed. > > My 'classOrMetaClass' instance var must be set to the class or metaClass for the method source so that I can correctly resolve identifiers within the source. If this is nil , I parse the source as an expression (i.e. a doIt expression). > > My 'workspace' instance variable can be set to a Workspace, so that I can resolve workspace variables. > > My 'environment' instance variable is the global namespace (this is initialized to Smalltalk, but can be set to a different environment). > > Example 1. > ranges := SHParserST80 new > classOrMetaClass: Object; > source: 'testMethod ^self'; > parse; > ranges > > ! > > Item was changed: > ----- Method: SHParserST80>>parse (in category 'parse') ----- > parse > "Parse the receiver's text as a Smalltalk method" > > + self parse: (parseAMethod ifNil: [ classOrMetaClass notNil ]). > - self parse: classOrMetaClass notNil. > errorBlock := nil! > > Item was added: > + ----- Method: SHParserST80>>parseAMethod: (in category 'accessing') ----- > + parseAMethod: aBoolean > + > + parseAMethod := aBoolean! > > Item was changed: > SHTextStyler subclass: #SHTextStylerST80 > + instanceVariableNames: 'classOrMetaClass workspace font parser formatAssignments environment sourceMap processedSourceMap pixelHeight attributesByPixelHeight parseAMethod' > - instanceVariableNames: 'classOrMetaClass workspace font parser formatAssignments environment sourceMap processedSourceMap pixelHeight attributesByPixelHeight' > classVariableNames: 'SubduedSyntaxHighlights SyntaxHighlightingAsYouType SyntaxHighlightingAsYouTypeAnsiAssignment SyntaxHighlightingAsYouTypeLeftArrowAssignment' > poolDictionaries: '' > category: 'ShoutCore-Styling'! > SHTextStylerST80 class > instanceVariableNames: 'styleTable textAttributesByPixelHeight'! > > !SHTextStylerST80 commentStamp: 'tween 8/27/2004 10:55' prior: 0! > I style Smalltalk methods and expressions. > > My 'styleTable' class instance var holds an array ofArrays which control how each token is styled/coloured. See my defaultStyleTable class method for its structure. > My styleTable can be changed by either modifying the defaultStyleTable class method and then executing SHTextStylerST80 initialize ; or by giving me a new styleTable through my #styleTable: class method. > > My 'textAttributesByPixelSize' class instance var contains a dictionary of dictionaries. > The key is a pixelSize and the value a Dictionary from token type Symbol to TextAttribute array. > It is created/maintained automatically. > > I also install these 3 preferences when my class initialize method is executed.... > #syntaxHighlightingAsYouType - controls whether methods are styled in browsers > #syntaxHighlightingAsYouTypeAnsiAssignment - controls whether assignments are formatted to be := > #syntaxHighlightingAsYouTypeLeftArrowAssignment - controls whether assignments are formatted to be _ > > I reimplement #unstyledTextFrom: so that TextActions are preserved in the unstyled text > > > > > > > ! > SHTextStylerST80 class > instanceVariableNames: 'styleTable textAttributesByPixelHeight'! > > Item was added: > + ----- Method: SHTextStylerST80>>parseAMethod: (in category 'accessing') ----- > + parseAMethod: aBoolean > + > + parseAMethod := aBoolean! > > Item was changed: > ----- Method: SHTextStylerST80>>rangesIn:setWorkspace: (in category 'private') ----- > rangesIn: aText setWorkspace: aBoolean > "Answer a collection of SHRanges by parsing aText. > When formatting it is not necessary to set the workspace, and this can make the parse take less time, so aBoolean specifies whether the parser should be given the workspace" > > | shoutParserClass | > "Switch parsers if we have to" > shoutParserClass := (classOrMetaClass ifNil:[Object]) shoutParserClass. > + parser class == shoutParserClass ifFalse:[parser := shoutParserClass new]. > + parser parseAMethod: parseAMethod. > - parser class = shoutParserClass ifFalse:[parser := shoutParserClass new]. > - > ^parser > rangesIn: aText asString > classOrMetaClass: classOrMetaClass > workspace: (aBoolean ifTrue:[workspace]) > environment: environment > ! > > From asqueaker at gmail.com Tue May 5 15:23:26 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 5 15:23:31 2015 Subject: [squeak-dev] The Trunk: ReleaseBuilder-kfr.121.mcz In-Reply-To: <5548d127.055c340a.48ab.68cdSMTPIN_ADDED_MISSING@mx.google.com> References: <5548d127.055c340a.48ab.68cdSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi, just so you know, back when we did 4.5 I used this method to initialize default preferences for the 4.5 release but Bert pointed out that we already have #defaultValueTableForCurrentRelease for setting up default preference values. Assuming it can be used even for pragma-preferences, then that method might be better to use since we can also generate a diff comparison between the current image settings and the "defaults" -- so someone can see what prefs differ in memory from the defaults. On Tue, May 5, 2015 at 9:18 AM, wrote: > Karl Ramberg uploaded a new version of ReleaseBuilder to project The Trunk: > http://source.squeak.org/trunk/ReleaseBuilder-kfr.121.mcz > > ==================== Summary ==================== > > Name: ReleaseBuilder-kfr.121 > Author: kfr > Time: 5 May 2015, 4:17:58.006 pm > UUID: e6126cb9-b0ff-ea45-8ebc-92a434ef0312 > Ancestors: ReleaseBuilder-mt.120 > > Changes to use SystemNavigation thoroughSenders: true > > =============== Diff against ReleaseBuilder-mt.120 =============== > > Item was changed: > ----- Method: ReleaseBuilder class>>setPreferences45 (in category 'preferences') ----- > setPreferences45 > > self setProjectBackground: self projectBackground45. > > Workspace shouldStyle: false. > SystemWindow reuseWindows: true. > TextEditor > autoEnclose: true ; > autoIndent: false ; > destructiveBackWord: false ; > blinkingCursor: false ; > dumbbellCursor: false. > BalloonMorph setBalloonColorTo: > (TranslucentColor > r: 0.92 > g: 0.92 > b: 0.706 > alpha: 0.75). > Preferences > installBrightWindowColors ; > insertionPointColor: Color red ; > enable: #scrollBarsWithoutMenuButton ; > enable: #gradientScrollBars ; > enable: #swapMouseButtons ; > enable: #annotationPanes ; > disable: #showSplitterHandles ; > enable: #showBoundsInHalo ; > disable: #alternateHandlesLook ; > disable: #roundedMenuCorners ; > disable: #roundedWindowCorners ; > enable: #traceMessages ; > - enable: #thoroughSenders ; > enable: #diffsWithPrettyPrint ; > disable: #alwaysShowVScrollbar ; > enable: #alternativeBrowseIt. > ProportionalSplitterMorph > smartHorizontalSplitters: false ; > smartVerticalSplitters: false. > PluggableButtonMorph roundedButtonCorners: false. > FillInTheBlankMorph roundedDialogCorners: false. > Workspace shouldStyle: false. > NetNameResolver enableIPv6: false. > + Browser listClassesHierarchically: true. > + SystemNavigation thoroughSenders: true! > - Browser listClassesHierarchically: true! > > Item was changed: > ----- Method: ReleaseBuilder class>>setPreferences46 (in category 'preferences') ----- > setPreferences46 > "Preferences class defaultValueTableForCurrentRelease" > > self setProjectBackground: self projectBackground46. > > "General User interaction" > Preferences > disable: #swapMouseButtons; > enable: #mouseOverForKeyboardFocus. > Morph indicateKeyboardFocus: true. > > "Text input." > TextEditor > autoEnclose: false ; > autoIndent: true ; > destructiveBackWord: false ; > blinkingCursor: true ; > dumbbellCursor: false. > Preferences > insertionPointColor: Color red. > PluggableTextMorph simpleFrameAdornments: false. > > "Windows" > Preferences installNormalWindowColors. > SystemWindow reuseWindows: false. > Model windowActiveOnFirstClick: false. "Not good for 800x600" > Preferences disable: #showSplitterHandles. > CornerGripMorph drawCornerResizeHandles: false. > ProportionalSplitterMorph > smartHorizontalSplitters: false ; > smartVerticalSplitters: false. > > "Scroll bars." > Preferences > enable: #scrollBarsNarrow; > enable: #scrollBarsOnRight; > disable: #alwaysHideHScrollbar; > disable: #alwaysShowHScrollbar; > disable: #alwaysShowVScrollbar. > ScrollBar > scrollBarsWithoutArrowButtons: true; > scrollBarsWithoutMenuButton: true. > ScrollPane > useRetractableScrollBars: false. > > "Rounded corners." > Morph preferredCornerRadius: 6. > Preferences disable: #roundedWindowCorners. > PluggableButtonMorph roundedButtonCorners: false. > FillInTheBlankMorph roundedDialogCorners: false. > MenuMorph roundedMenuCorners: false. > ScrollBar roundedScrollBarLook: false. > > "Gradients." > Preferences disable: #gradientScrollBars. > SystemWindow gradientWindow: false. > MenuMorph gradientMenu: false. > PluggableButtonMorph gradientButton: false. > > "Shadows" > Preferences enable: #menuAppearance3d. > Morph useSoftDropShadow: true. > > "Lists and Trees" > PluggableListMorph > filterableLists: true; > clearFilterAutomatically: false; > highlightHoveredRow: true; > menuRequestUpdatesSelection: true. > PluggableTreeMorph > filterByLabelsOnly: false; > maximumSearchDepth: 1. > LazyListMorph > listSelectionTextColor: Color black; > listSelectionColor: (Color r: 0.72 g: 0.72 b: 0.9). > > "Standard Tools" > BalloonMorph setBalloonColorTo: > (TranslucentColor r: 0.92 g: 0.92 b: 0.706 alpha: 0.75). > Workspace shouldStyle: false. > Browser > listClassesHierarchically: true; > showClassIcons: true; > showMessageIcons: true; > sortMessageCategoriesAlphabetically: true. > Preferences > enable: #annotationPanes; > enable: #optionalButtons; > enable: #diffsWithPrettyPrint; > enable: #traceMessages ; > - enable: #thoroughSenders ; > enable: #alternativeBrowseIt; > enable: #menuWithIcons; > enable: #visualExplorer. > + SystemNavigation thoroughSenders: true. > + > - > "Halo" > Preferences > enable: #showBoundsInHalo ; > disable: #alternateHandlesLook. > > "Network" > NetNameResolver enableIPv6: false. > + > + ! > - ! > > From asqueaker at gmail.com Tue May 5 15:25:10 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 5 15:25:13 2015 Subject: [squeak-dev] The Trunk: System-kfr.735.mcz In-Reply-To: <5548d208.ea0a340a.73ba.ffff8728SMTPIN_ADDED_MISSING@mx.google.com> References: <5548d208.ea0a340a.73ba.ffff8728SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Annnd, it looks like you are aware of that. :) Please disregard my last note, I'm reading chronologically. On Tue, May 5, 2015 at 9:21 AM, wrote: > Karl Ramberg uploaded a new version of System to project The Trunk: > http://source.squeak.org/trunk/System-kfr.735.mcz > > ==================== Summary ==================== > > Name: System-kfr.735 > Author: kfr > Time: 5 May 2015, 4:21:01.607 pm > UUID: 6facccb7-8706-c243-a18d-f94b87f4513e > Ancestors: System-topa.734 > > Changes to use SystemNavigation thoroughSenders: true > > =============== Diff against System-topa.734 =============== > > Item was changed: > ----- Method: Preferences class>>defaultValueTableForCurrentRelease (in category 'misc') ----- > defaultValueTableForCurrentRelease > "Answer a table defining default values for all the preferences in the release. Returns a list of (pref-symbol, boolean-symbol) pairs" > > ^ #( > (abbreviatedBrowserButtons false) > (alternativeBrowseIt false) > (annotationPanes false) > (areaFillsAreTolerant false) > (areaFillsAreVeryTolerant false) > (automaticFlapLayout true) > (automaticKeyGeneration false) > (automaticPlatformSettings true) > (automaticViewerPlacement true) > (balloonHelpEnabled true) > (balloonHelpInMessageLists false) > (batchPenTrails false) > (canRecordWhilePlaying false) > (capitalizedReferences true) > (caseSensitiveFinds false) > (cautionBeforeClosing false) > (changeSetVersionNumbers true) > (checkForSlips true) > (checkForUnsavedProjects true) > (classicNavigatorEnabled false) > (clickOnLabelToEdit false) > (cmdDotEnabled true) > (collapseWindowsInPlace false) > (compactViewerFlaps false) > (compressFlashImages false) > (confirmFirstUseOfStyle true) > (conversionMethodsAtFileOut false) > (debugHaloHandle true) > (debugPrintSpaceLog false) > (debugShowDamage false) > (decorateBrowserButtons true) > (diffsInChangeList true) > (diffsWithPrettyPrint false) > (dismissAllOnOptionClose false) > (dragNDropWithAnimation false) > (eToyFriendly false) > (eToyLoginEnabled false) > (enableLocalSave true) > (extractFlashInHighQuality true) > (extractFlashInHighestQuality false) > (fastDragWindowForMorphic true) > (fenceEnabled true) > (fullScreenLeavesDeskMargins true) > (haloTransitions false) > (hiddenScrollBars false) > (higherPerformance false) > (honorDesktopCmdKeys true) > (ignoreStyleIfOnlyBold true) > (includeSoundControlInNavigator false) > (infiniteUndo false) > (logDebuggerStackToFile true) > (magicHalos false) > (menuButtonInToolPane false) > (menuColorFromWorld false) > (menuKeyboardControl false) > (modalColorPickers true) > (mouseOverForKeyboardFocus false) > (mouseOverHalos false) > (mvcProjectsAllowed true) > (navigatorOnLeftEdge true) > (noviceMode false) > (okToReinitializeFlaps true) > (optionalButtons true) > (passwordsOnPublish false) > (personalizedWorldMenu true) > (postscriptStoredAsEPS false) > (projectViewsInWindows true) > (projectZoom true) > (projectsSentToDisk false) > (propertySheetFromHalo false) > (readDocumentAtStartup true) > (restartAlsoProceeds false) > (reverseWindowStagger true) > (roundedMenuCorners true) > (roundedWindowCorners true) > (scrollBarsNarrow false) > (scrollBarsOnRight true) > (scrollBarsWithoutMenuButton false) > (gradientScrollBars true) > (securityChecksEnabled false) > (selectiveHalos false) > (showBoundsInHalo false) > (showDirectionForSketches false) > (showDirectionHandles false) > (showFlapsWhenPublishing false) > (showProjectNavigator false) > (showSecurityStatus true) > (showSharedFlaps true) > (signProjectFiles true) > (simpleMenus false) > (smartUpdating true) > (soundQuickStart false) > (stopSoundWhenDone false) > (soundEnabled true) > (startInUntrustedDirectory false) > (systemWindowEmbedOK false) > - (thoroughSenders true) > (tileTranslucentDrag true) > (timeStampsInMenuTitles true) > (turnOffPowerManager false) > (twentyFourHourFileStamps true) > (typeCheckingInTileScripting true) > (uniTilesClassic true) > (uniqueNamesInHalos false) > (universalTiles false) > (unlimitedPaintArea false) > (useButtonProprtiesToFire false) > (useUndo true) > (viewersInFlaps true) > (warnAboutInsecureContent true) > (warnIfNoChangesFile true) > (warnIfNoSourcesFile true)) > > > " > Preferences defaultValueTableForCurrentRelease do: > [:pair | (Preferences preferenceAt: pair first ifAbsent: [nil]) ifNotNilDo: > [:pref | pref defaultValue: (pair last == true)]]. > Preferences chooseInitialSettings. > "! > > Item was changed: > ----- Method: Preferences class>>outOfTheBox (in category 'themes') ----- > outOfTheBox > "The default out-of-the-box preference settings for Squeak 3.2. The 'alternative' window-look and scrollbar-look are used. Button panes are used but not annotation panes. Scrollbars are on the right and do not flop out." > > + self setPreferencesFrom: self defaultValueTableForCurrentRelease. > + SystemNavigation thoroughSenders: true! > - self setPreferencesFrom: self defaultValueTableForCurrentRelease! > > From commits at source.squeak.org Tue May 5 16:24:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 16:24:02 2015 Subject: [squeak-dev] The Trunk: System-kfr.736.mcz Message-ID: Karl Ramberg uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-kfr.736.mcz ==================== Summary ==================== Name: System-kfr.736 Author: kfr Time: 5 May 2015, 6:23:07.018 pm UUID: eb0a3448-a767-5e4e-a169-c1a70c984a87 Ancestors: System-kfr.735 Changes to use pragma preferences where implemented =============== Diff against System-kfr.735 =============== Item was changed: ----- Method: Preferences class>>defaultValueTableForCurrentRelease (in category 'misc') ----- defaultValueTableForCurrentRelease "Answer a table defining default values for all the preferences in the release. Returns a list of (pref-symbol, boolean-symbol) pairs" ^ #( (abbreviatedBrowserButtons false) (alternativeBrowseIt false) (annotationPanes false) (areaFillsAreTolerant false) (areaFillsAreVeryTolerant false) (automaticFlapLayout true) (automaticKeyGeneration false) (automaticPlatformSettings true) (automaticViewerPlacement true) (balloonHelpEnabled true) (balloonHelpInMessageLists false) (batchPenTrails false) - (canRecordWhilePlaying false) (capitalizedReferences true) (caseSensitiveFinds false) (cautionBeforeClosing false) (changeSetVersionNumbers true) (checkForSlips true) (checkForUnsavedProjects true) (classicNavigatorEnabled false) - (clickOnLabelToEdit false) (cmdDotEnabled true) (collapseWindowsInPlace false) (compactViewerFlaps false) (compressFlashImages false) (confirmFirstUseOfStyle true) (conversionMethodsAtFileOut false) (debugHaloHandle true) (debugPrintSpaceLog false) (debugShowDamage false) (decorateBrowserButtons true) (diffsInChangeList true) (diffsWithPrettyPrint false) (dismissAllOnOptionClose false) (dragNDropWithAnimation false) (eToyFriendly false) (eToyLoginEnabled false) (enableLocalSave true) (extractFlashInHighQuality true) (extractFlashInHighestQuality false) (fastDragWindowForMorphic true) (fenceEnabled true) (fullScreenLeavesDeskMargins true) (haloTransitions false) - (hiddenScrollBars false) (higherPerformance false) (honorDesktopCmdKeys true) - (ignoreStyleIfOnlyBold true) (includeSoundControlInNavigator false) (infiniteUndo false) (logDebuggerStackToFile true) (magicHalos false) (menuButtonInToolPane false) (menuColorFromWorld false) (menuKeyboardControl false) (modalColorPickers true) (mouseOverForKeyboardFocus false) (mouseOverHalos false) (mvcProjectsAllowed true) (navigatorOnLeftEdge true) (noviceMode false) (okToReinitializeFlaps true) (optionalButtons true) (passwordsOnPublish false) (personalizedWorldMenu true) (postscriptStoredAsEPS false) (projectViewsInWindows true) (projectZoom true) (projectsSentToDisk false) (propertySheetFromHalo false) (readDocumentAtStartup true) (restartAlsoProceeds false) (reverseWindowStagger true) (roundedMenuCorners true) (roundedWindowCorners true) (scrollBarsNarrow false) (scrollBarsOnRight true) - (scrollBarsWithoutMenuButton false) (gradientScrollBars true) (securityChecksEnabled false) (selectiveHalos false) (showBoundsInHalo false) (showDirectionForSketches false) (showDirectionHandles false) (showFlapsWhenPublishing false) (showProjectNavigator false) (showSecurityStatus true) (showSharedFlaps true) (signProjectFiles true) (simpleMenus false) (smartUpdating true) - (soundQuickStart false) - (stopSoundWhenDone false) - (soundEnabled true) (startInUntrustedDirectory false) (systemWindowEmbedOK false) (tileTranslucentDrag true) (timeStampsInMenuTitles true) (turnOffPowerManager false) (twentyFourHourFileStamps true) (typeCheckingInTileScripting true) (uniTilesClassic true) (uniqueNamesInHalos false) (universalTiles false) (unlimitedPaintArea false) + (useButtonPropertiesToFire false) - (useButtonProprtiesToFire false) (useUndo true) (viewersInFlaps true) (warnAboutInsecureContent true) (warnIfNoChangesFile true) (warnIfNoSourcesFile true)) " Preferences defaultValueTableForCurrentRelease do: [:pair | (Preferences preferenceAt: pair first ifAbsent: [nil]) ifNotNilDo: [:pref | pref defaultValue: (pair last == true)]]. Preferences chooseInitialSettings. "! Item was changed: ----- Method: Preferences class>>outOfTheBox (in category 'themes') ----- outOfTheBox "The default out-of-the-box preference settings for Squeak 3.2. The 'alternative' window-look and scrollbar-look are used. Button panes are used but not annotation panes. Scrollbars are on the right and do not flop out." self setPreferencesFrom: self defaultValueTableForCurrentRelease. + SystemNavigation thoroughSenders: true. + SystemWindow clickOnLabelToEdit: true. + Text ignoreStyleIfOnlyBold: true. + MenuMorph roundedMenuCorners: true. + ScrollBar scrollBarsWithoutMenuButton: true. + SoundPlayer soundQuickStart: false. + SoundPlayer stopSoundWhenDone: false. + SoundService soundEnabled: true. + SoundRecorder canRecordWhilePlaying:false.! - SystemNavigation thoroughSenders: true! Item was added: + ----- Method: Preferences class>>useButtonPropertiesToFire (in category 'standard queries') ----- + useButtonPropertiesToFire + ^ self + valueOfFlag: #useButtonProprtiesToFire + ifAbsent: [ false ]! Item was removed: - ----- Method: Preferences class>>useButtonProprtiesToFire (in category 'standard queries') ----- - useButtonProprtiesToFire - ^ self - valueOfFlag: #useButtonProprtiesToFire - ifAbsent: [ false ]! From commits at source.squeak.org Tue May 5 16:25:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 16:25:26 2015 Subject: [squeak-dev] The Trunk: EToys-kfr.126.mcz Message-ID: Karl Ramberg uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-kfr.126.mcz ==================== Summary ==================== Name: EToys-kfr.126 Author: kfr Time: 5 May 2015, 6:24:47.803 pm UUID: a325f205-34bf-e24b-8fb4-173d05fa300b Ancestors: EToys-kfr.125 Fix spelling =============== Diff against EToys-kfr.125 =============== Item was changed: ----- Method: Player>>tearOffButtonToFireScriptForSelector: (in category 'costume') ----- tearOffButtonToFireScriptForSelector: aSelector "Tear off a button to fire the script for the given selector" | aButton props | + Preferences useButtonPropertiesToFire ifFalse: - Preferences useButtonProprtiesToFire ifFalse: [aButton := ScriptActivationButton new. aButton initializeForPlayer: self uniclassScript: (self class scripts at: aSelector). ^ aButton openInHand]. (aButton := RectangleMorph new) useRoundedCorners; color: Color yellow. props := aButton ensuredButtonProperties. props target: self; actionSelector: #runScript:; arguments: {aSelector}; delayBetweenFirings: 80; actWhen: #mouseUp; mouseDownHaloWidth: 8; wantsRolloverIndicator: true; mouseOverHaloWidth: 5; establishEtoyLabelWording. aButton width: aButton submorphs first width + 20; height: 20. self currentHand attachMorph: aButton. ! From karlramberg at gmail.com Tue May 5 16:34:43 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 5 16:34:48 2015 Subject: [squeak-dev] The Trunk: System-kfr.735.mcz In-Reply-To: References: <5548d208.ea0a340a.73ba.ffff8728SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: And I just went through these to use the pragma preferences where available. Karl On Tue, May 5, 2015 at 5:25 PM, Chris Muller wrote: > Annnd, it looks like you are aware of that. :) Please disregard my > last note, I'm reading chronologically. > > On Tue, May 5, 2015 at 9:21 AM, wrote: > > Karl Ramberg uploaded a new version of System to project The Trunk: > > http://source.squeak.org/trunk/System-kfr.735.mcz > > > > ==================== Summary ==================== > > > > Name: System-kfr.735 > > Author: kfr > > Time: 5 May 2015, 4:21:01.607 pm > > UUID: 6facccb7-8706-c243-a18d-f94b87f4513e > > Ancestors: System-topa.734 > > > > Changes to use SystemNavigation thoroughSenders: true > > > > =============== Diff against System-topa.734 =============== > > > > Item was changed: > > ----- Method: Preferences class>>defaultValueTableForCurrentRelease > (in category 'misc') ----- > > defaultValueTableForCurrentRelease > > "Answer a table defining default values for all the preferences > in the release. Returns a list of (pref-symbol, boolean-symbol) pairs" > > > > ^ #( > > (abbreviatedBrowserButtons false) > > (alternativeBrowseIt false) > > (annotationPanes false) > > (areaFillsAreTolerant false) > > (areaFillsAreVeryTolerant false) > > (automaticFlapLayout true) > > (automaticKeyGeneration false) > > (automaticPlatformSettings true) > > (automaticViewerPlacement true) > > (balloonHelpEnabled true) > > (balloonHelpInMessageLists false) > > (batchPenTrails false) > > (canRecordWhilePlaying false) > > (capitalizedReferences true) > > (caseSensitiveFinds false) > > (cautionBeforeClosing false) > > (changeSetVersionNumbers true) > > (checkForSlips true) > > (checkForUnsavedProjects true) > > (classicNavigatorEnabled false) > > (clickOnLabelToEdit false) > > (cmdDotEnabled true) > > (collapseWindowsInPlace false) > > (compactViewerFlaps false) > > (compressFlashImages false) > > (confirmFirstUseOfStyle true) > > (conversionMethodsAtFileOut false) > > (debugHaloHandle true) > > (debugPrintSpaceLog false) > > (debugShowDamage false) > > (decorateBrowserButtons true) > > (diffsInChangeList true) > > (diffsWithPrettyPrint false) > > (dismissAllOnOptionClose false) > > (dragNDropWithAnimation false) > > (eToyFriendly false) > > (eToyLoginEnabled false) > > (enableLocalSave true) > > (extractFlashInHighQuality true) > > (extractFlashInHighestQuality false) > > (fastDragWindowForMorphic true) > > (fenceEnabled true) > > (fullScreenLeavesDeskMargins true) > > (haloTransitions false) > > (hiddenScrollBars false) > > (higherPerformance false) > > (honorDesktopCmdKeys true) > > (ignoreStyleIfOnlyBold true) > > (includeSoundControlInNavigator false) > > (infiniteUndo false) > > (logDebuggerStackToFile true) > > (magicHalos false) > > (menuButtonInToolPane false) > > (menuColorFromWorld false) > > (menuKeyboardControl false) > > (modalColorPickers true) > > (mouseOverForKeyboardFocus false) > > (mouseOverHalos false) > > (mvcProjectsAllowed true) > > (navigatorOnLeftEdge true) > > (noviceMode false) > > (okToReinitializeFlaps true) > > (optionalButtons true) > > (passwordsOnPublish false) > > (personalizedWorldMenu true) > > (postscriptStoredAsEPS false) > > (projectViewsInWindows true) > > (projectZoom true) > > (projectsSentToDisk false) > > (propertySheetFromHalo false) > > (readDocumentAtStartup true) > > (restartAlsoProceeds false) > > (reverseWindowStagger true) > > (roundedMenuCorners true) > > (roundedWindowCorners true) > > (scrollBarsNarrow false) > > (scrollBarsOnRight true) > > (scrollBarsWithoutMenuButton false) > > (gradientScrollBars true) > > (securityChecksEnabled false) > > (selectiveHalos false) > > (showBoundsInHalo false) > > (showDirectionForSketches false) > > (showDirectionHandles false) > > (showFlapsWhenPublishing false) > > (showProjectNavigator false) > > (showSecurityStatus true) > > (showSharedFlaps true) > > (signProjectFiles true) > > (simpleMenus false) > > (smartUpdating true) > > (soundQuickStart false) > > (stopSoundWhenDone false) > > (soundEnabled true) > > (startInUntrustedDirectory false) > > (systemWindowEmbedOK false) > > - (thoroughSenders true) > > (tileTranslucentDrag true) > > (timeStampsInMenuTitles true) > > (turnOffPowerManager false) > > (twentyFourHourFileStamps true) > > (typeCheckingInTileScripting true) > > (uniTilesClassic true) > > (uniqueNamesInHalos false) > > (universalTiles false) > > (unlimitedPaintArea false) > > (useButtonProprtiesToFire false) > > (useUndo true) > > (viewersInFlaps true) > > (warnAboutInsecureContent true) > > (warnIfNoChangesFile true) > > (warnIfNoSourcesFile true)) > > > > > > " > > Preferences defaultValueTableForCurrentRelease do: > > [:pair | (Preferences preferenceAt: pair first ifAbsent: [nil]) > ifNotNilDo: > > [:pref | pref defaultValue: (pair last == > true)]]. > > Preferences chooseInitialSettings. > > "! > > > > Item was changed: > > ----- Method: Preferences class>>outOfTheBox (in category 'themes') > ----- > > outOfTheBox > > "The default out-of-the-box preference settings for Squeak 3.2. > The 'alternative' window-look and scrollbar-look are used. Button panes > are used but not annotation panes. Scrollbars are on the right and do not > flop out." > > > > + self setPreferencesFrom: self defaultValueTableForCurrentRelease. > > + SystemNavigation thoroughSenders: true! > > - self setPreferencesFrom: self defaultValueTableForCurrentRelease! > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150505/ef34cc31/attachment-0001.htm From commits at source.squeak.org Tue May 5 21:14:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 21:14:17 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.968.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.968.mcz ==================== Summary ==================== Name: Morphic-cmm.968 Author: cmm Time: 5 May 2015, 4:13:30.633 pm UUID: 906a31d4-1930-44d0-971f-edcad6e71535 Ancestors: Morphic-mt.967 - The new simultaneous adjustment of sibling smart-splitters requires that dragging a smart-splitter equally affect siblings to stay put. - The new simultaneous sibling adjustment feature is fixed for horizontal splitters. =============== Diff against Morphic-mt.967 =============== Item was changed: ----- Method: ProportionalSplitterMorph>>mouseDown: (in category 'events') ----- mouseDown: anEvent "If the user manually drags me, don't override him with auto positioning." anEvent redButtonChanged + ifTrue: [ self withSiblingSplittersDo: [ : each | each stopStepping ] ] - ifTrue: [ self stopStepping ] ifFalse: [ anEvent shiftPressed ifTrue: [ self startStepping ] ifFalse: [ self startStepping. + self withSiblingSplittersDo: [ : each | each startStepping ] ] ]. - self siblingSplittersDo: [ : each | each startStepping ] ] ]. (self class showSplitterHandles not and: [ self bounds containsPoint: anEvent cursorPoint ]) ifTrue: [ oldColor := self color. self color: Color black ]. ^ super mouseDown: anEvent! Item was changed: ----- Method: ProportionalSplitterMorph>>siblingSplittersDo: (in category 'adjacent splitters') ----- siblingSplittersDo: aBlock + owner ifNotNil: - ^ owner ifNotNil: [ owner submorphsDo: [ : each | ((each isKindOf: self class) and: [ self splitsTopAndBottom = each splitsTopAndBottom and: [ each ~= self ] ]) ifTrue: [ aBlock value: each ] ] ]! Item was changed: ----- Method: ProportionalSplitterMorph>>topBottomCorrection (in category 'layout') ----- topBottomCorrection ^ self top < self topBoundary ifTrue: [ self topBoundary - self top ] ifFalse: [ self bottom > (self bottomBoundary) ifTrue: [ self bottomBoundary - self bottom ] ifFalse: [ | wsAbove wsBelow | wsAbove := self canEncroachWhiteSpaceOf: leftOrTop. wsBelow := self canEncroachWhiteSpaceOf: rightOrBottom. wsAbove ifTrue: [ wsBelow ifTrue: [ self splitterBelow + ifNil: [0] + ifNotNil: [ : below | below reduceTopBottomImbalance min: 0 ] ] - ifNil: [ 0 ] - ifNotNil: [ : below | below topBottomCorrection min: 0 ] ] ifFalse: [ (self top > self topBoundary) ifTrue: [-2] ifFalse: [0] ] ] ifFalse: [ wsBelow ifTrue: [ (self bottom < self bottomBoundary) ifTrue: [2] ifFalse: [0] ] ifFalse: [ self splitterBelow + ifNil: [0] + ifNotNil: [ : below | below reduceTopBottomImbalance max: 0 ] ] ] ] ]! - ifNil: [ 0 ] - ifNotNil: [ : below | below topBottomCorrection max: 0 ] ] ] ] ]! Item was added: + ----- Method: ProportionalSplitterMorph>>withSiblingSplittersDo: (in category 'adjacent splitters') ----- + withSiblingSplittersDo: aBlock + aBlock value: self. + self siblingSplittersDo: aBlock! From cunningham.cb at gmail.com Tue May 5 21:20:01 2015 From: cunningham.cb at gmail.com (Chris Cunningham) Date: Tue May 5 21:20:02 2015 Subject: [squeak-dev] Re: incorrect Shout rendering in ObjectExplorer In-Reply-To: <1430831498739-4824604.post@n4.nabble.com> References: <1430831498739-4824604.post@n4.nabble.com> Message-ID: very nice. On Tue, May 5, 2015 at 6:11 AM, marcel.taeumel wrote: > Works now: http://forum.world.st/The-Trunk-Tools-mt-621-mcz-td4824603.html > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/incorrect-Shout-rendering-in-ObjectExplorer-tp4824413p4824604.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150505/82261a3c/attachment.htm From commits at source.squeak.org Tue May 5 21:55:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 5 21:55:07 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150505215506.16853.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008287.html Name: Tools-topa.620 Ancestors: Tools-mt.619 Use a temporary instead of an ensure around a return. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008288.html Name: Monticello-eem.614 Ancestors: Monticello-mt.613 Check for an empty log message before accepting a save. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008289.html Name: Collections-ul.625 Ancestors: Collections-ul.624 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008290.html Name: Collections-ul.624 Ancestors: Collections-tfel.623 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008291.html Name: ToolBuilder-Morphic-mt.145 Ancestors: ToolBuilder-Morphic-mt.144 Give models/tools the chance to restyle dependent widgets (text fields) if needed. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008292.html Name: ToolBuilder-Morphic-mt.146 Ancestors: ToolBuilder-Morphic-mt.145 Spelling improved for last commit about re-styling in text morphs. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008293.html Name: ShoutCore-ul.49 Ancestors: ShoutCore-ul.48 Fix styling in Inspectors and ObjectExplorers. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008294.html Name: ShoutCore-mt.50 Ancestors: ShoutCore-ul.49 Remove Tools dependency. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008295.html Name: Tools-mt.621 Ancestors: Tools-topa.620 Fixes styling in Inspector and Object Explorer. Thanks to Levente for the idea of #parseAMethod: in Shout styler. :-) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008296.html Name: ReleaseBuilder-kfr.121 Ancestors: ReleaseBuilder-mt.120 Changes to use SystemNavigation thoroughSenders: true ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008297.html Name: System-kfr.735 Ancestors: System-topa.734 Changes to use SystemNavigation thoroughSenders: true ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008298.html Name: System-kfr.736 Ancestors: System-kfr.735 Changes to use pragma preferences where implemented ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008299.html Name: EToys-kfr.126 Ancestors: EToys-kfr.125 Fix spelling ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008300.html Name: Morphic-cmm.968 Ancestors: Morphic-mt.967 - The new simultaneous adjustment of sibling smart-splitters requires that dragging a smart-splitter equally affect siblings to stay put. - The new simultaneous sibling adjustment feature is fixed for horizontal splitters. ============================================= From commits at source.squeak.org Wed May 6 00:40:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 00:40:15 2015 Subject: [squeak-dev] The Trunk: Collections-ul.632.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.632.mcz ==================== Summary ==================== Name: Collections-ul.632 Author: ul Time: 5 May 2015, 1:10:58.584 am UUID: 5581dccd-80b4-4a89-8918-450ff62093da Ancestors: Collections-mt.631 Removed MutexForPicking and RandomForPicking from Collection along with the methods referencing them, because the accessor methods were private, and they were only intended to be used for shuffling. Separated #groupBy: from #groupBy:having:. =============== Diff against Collections-mt.631 =============== Item was changed: Object subclass: #Collection instanceVariableNames: '' + classVariableNames: '' - classVariableNames: 'MutexForPicking RandomForPicking' poolDictionaries: '' category: 'Collections-Abstract'! !Collection commentStamp: '' prior: 0! I am the abstract superclass of all classes that represent a group of elements.! Item was changed: ----- Method: Collection class>>initialize (in category 'class initialization') ----- initialize "Set up a Random number generator to be used by atRandom when the user does not feel like creating his own Random generator." - RandomForPicking := Random new. - MutexForPicking := Semaphore forMutualExclusion. Smalltalk addToStartUpList: self! Item was removed: - ----- Method: Collection class>>mutexForPicking (in category 'private') ----- - mutexForPicking - ^ MutexForPicking! Item was removed: - ----- Method: Collection class>>randomForPicking (in category 'private') ----- - randomForPicking - - self deprecated: 'Use ThreadSafeRandom value instead. It''s not thread-safe to use this instance without the unaccessible MutexForPicking semaphore.'. - ^ RandomForPicking! Item was removed: - ----- Method: Collection class>>startUp (in category 'system startup') ----- - startUp - "Reseed the random generator at startup time such that a reloaded - project will not repeat a previous pseudo-random sequence when - selecting at random from a collection." - - MutexForPicking - critical: [RandomForPicking initialize]! Item was added: + ----- Method: Collection>>groupBy: (in category 'enumerating') ----- + groupBy: keyBlock + "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return them." + + | result | + result := Dictionary new. + self do: [ :each | + | key | + key := keyBlock value: each. + (result at: key ifAbsentPut: [ OrderedCollection new ]) + add: each ]. + ^result! Item was changed: ----- Method: Collection>>groupBy:having: (in category 'enumerating') ----- groupBy: keyBlock having: selectBlock "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return those collections allowed by selectBlock." + + ^(self groupBy: keyBlock) select: selectBlock! - | result | - result := Dictionary new. - self do: - [ : each | | key | - key := keyBlock value: each. - (result - at: key - ifAbsentPut: [ OrderedCollection new ]) add: each ]. - ^ result select: selectBlock! From commits at source.squeak.org Wed May 6 00:40:23 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 00:40:26 2015 Subject: [squeak-dev] The Trunk: Collections-ul.633.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.633.mcz ==================== Summary ==================== Name: Collections-ul.633 Author: ul Time: 5 May 2015, 7:52:50.385 pm UUID: 4937e4f5-8560-437c-a820-0cae464e47a0 Ancestors: Collections-ul.632 Don't try to use Character's ClassificationTable when the new class variables are not initialized properly. This is a possible workaround to fix the Spur bootstrap. =============== Diff against Collections-ul.632 =============== Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "Answer the receiver's matching lowercase Character." + AlphaNumericMask ifNotNil: [ + value > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ] ]. - value > 255 ifFalse: [ - | result | - (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 - ifTrue: [ ^self class value: result ] ]. ^self class value: (self encodedCharSet toLowercaseCode: value)! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "Answer the receiver's matching uppercase Character." + AlphaNumericMask ifNotNil: [ + value > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ] ]. - value > 255 ifFalse: [ - | result | - (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 - ifTrue: [ ^self class value: result ] ]. ^self class value: (self encodedCharSet toUppercaseCode: value)! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + AlphaNumericMask ifNotNil: [ + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ] ]. - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + DigitBit ifNotNil: [ + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ] ]. - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + LetterMask ifNotNil: [ + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ] ]. - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ]. ^self encodedCharSet isLetter: self! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + AlphaNumericMask ifNotNil: [ + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ] ]. - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + AlphaNumericMask ifNotNil: [ + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ] ]. - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! From commits at source.squeak.org Wed May 6 00:41:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 00:41:02 2015 Subject: [squeak-dev] The Trunk: Traits-ul.305.mcz Message-ID: Levente Uzonyi uploaded a new version of Traits to project The Trunk: http://source.squeak.org/trunk/Traits-ul.305.mcz ==================== Summary ==================== Name: Traits-ul.305 Author: ul Time: 26 April 2015, 5:11:03.366 pm UUID: 34df02d0-c86a-4038-a909-e1d332374322 Ancestors: Traits-mt.304 - cache the source files during recompilation =============== Diff against Traits-mt.304 =============== Item was changed: ----- Method: Trait class>>unloadTraits (in category 'load-unload') ----- unloadTraits "Trait unloadTraits" Trait traitImpl == self ifTrue:[Trait traitImpl: nil]. self removeAllTraits. Behavior compileSilently: 'updateTraits' classified: 'accessing'. ClassDescription removeSelectorSilently: #updateTraits. ClassOrganizer organization classify: #traitComposition under: 'accessing'. (MCPackage named: 'Traits') unload. ClassOrganizer removeSelectorSilently: #traitComposition. Behavior removeSelectorSilently: #updateTraits. + CurrentReadOnlySourceFiles cacheDuring: [ + Compiler recompileAll ]! - Compiler recompileAll.! From commits at source.squeak.org Wed May 6 07:34:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 07:34:06 2015 Subject: [squeak-dev] The Trunk: Monticello-mt.615.mcz Message-ID: Marcel Taeumel uploaded a new version of Monticello to project The Trunk: http://source.squeak.org/trunk/Monticello-mt.615.mcz ==================== Summary ==================== Name: Monticello-mt.615 Author: mt Time: 6 May 2015, 9:33:45.98 am UUID: 0eaf95a3-eb08-b245-96d4-713242d796c2 Ancestors: Monticello-eem.614 Some ShoutCore dependencies untangled. =============== Diff against Monticello-eem.614 =============== Item was added: + ----- Method: MCPatchBrowser>>aboutToStyle: (in category 'styling') ----- + aboutToStyle: aStyler + + selection ifNotNil: [ + selection isConflict ifTrue: [ ^false ]. + (selection isAddition or: [ selection isRemoval ]) ifTrue: [ + selection definition isOrganizationDefinition ifTrue: [ ^false ]. + aStyler classOrMetaClass: self selectedClassOrMetaClass. + ^true ] ]. + ^false! Item was added: + ----- Method: MCSnapshotBrowser>>aboutToStyle: (in category 'styling') ----- + aboutToStyle: aStyler + + | classDefinition shouldStyle | + classSelection ifNil: [ ^false ]. + self switchIsComment ifTrue: [ ^false ]. + methodSelection + ifNotNil: [ + classDefinition := items + detect: [:ea | + ea isClassDefinition and: [ ea className = classSelection ] ] + ifNone: [ + (Smalltalk at: classSelection ifAbsent: [ Object ]) asClassDefinition ]. + shouldStyle := true ] + ifNil: [ + classDefinition := nil. + shouldStyle := categorySelection ~= self extensionsCategory ]. + aStyler + environment: self; + classOrMetaClass: (classDefinition ifNotNil: [ + SHMCClassDefinition + classDefinition: classDefinition + items: items + meta: switch = #class ]). + ^shouldStyle! Item was added: + ----- Method: MCSnapshotBrowser>>bindingOf: (in category 'binding') ----- + bindingOf: aSymbol + + (Smalltalk bindingOf: aSymbol) ifNotNil: [ :binding | ^binding ]. + items do: [ :each | + (each isClassDefinition and: [ + each className = aSymbol ]) ifTrue: [ ^aSymbol -> each ] ]. + ^nil! From commits at source.squeak.org Wed May 6 07:36:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 07:36:30 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.969.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.969.mcz ==================== Summary ==================== Name: Morphic-mt.969 Author: mt Time: 6 May 2015, 9:35:50.409 am UUID: 573edefb-1ade-1e43-a783-ebb7e48528f9 Ancestors: Morphic-cmm.968 Some ShoutCore dependencies untangled. =============== Diff against Morphic-cmm.968 =============== Item was added: + ----- Method: Model>>aboutToStyle: (in category '*morphic') ----- + aboutToStyle: aStyler + "Default implementation for text styling. No changes in styler configuration but we are OK to style our contents." + + ^ true! From commits at source.squeak.org Wed May 6 07:37:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 07:37:04 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Morphic-mt.147.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.147.mcz ==================== Summary ==================== Name: ToolBuilder-Morphic-mt.147 Author: mt Time: 6 May 2015, 9:36:40.545 am UUID: b015d17a-d6d0-e148-b80f-ac9272ed9328 Ancestors: ToolBuilder-Morphic-mt.146 Some ShoutCore dependencies untangled. =============== Diff against ToolBuilder-Morphic-mt.146 =============== Item was changed: ----- Method: PluggableTextMorphPlus>>okToStyle (in category 'testing') ----- okToStyle + + ^ styler + ifNil:[false] + ifNotNil: [:s | model aboutToStyle: s]! - styler ifNil:[^false]. - (model respondsTo: #aboutToStyle: ) ifFalse:[^true]. - ^model aboutToStyle: styler - ! From commits at source.squeak.org Wed May 6 07:37:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 07:38:00 2015 Subject: [squeak-dev] The Trunk: ShoutCore-mt.51.mcz Message-ID: Marcel Taeumel uploaded a new version of ShoutCore to project The Trunk: http://source.squeak.org/trunk/ShoutCore-mt.51.mcz ==================== Summary ==================== Name: ShoutCore-mt.51 Author: mt Time: 6 May 2015, 9:37:51.463 am UUID: 58d9bae4-356c-8745-940b-f394a6dde152 Ancestors: ShoutCore-mt.50 Some ShoutCore dependencies untangled. =============== Diff against ShoutCore-mt.50 =============== Item was removed: - ----- Method: MCPatchBrowser>>aboutToStyle: (in category '*ShoutCore') ----- - aboutToStyle: aStyler - - selection ifNotNil: [ - selection isConflict ifTrue: [ ^false ]. - (selection isAddition or: [ selection isRemoval ]) ifTrue: [ - selection definition isOrganizationDefinition ifTrue: [ ^false ]. - aStyler classOrMetaClass: self selectedClassOrMetaClass. - ^true ] ]. - ^false! Item was removed: - ----- Method: MCSnapshotBrowser>>aboutToStyle: (in category '*ShoutCore') ----- - aboutToStyle: aStyler - - | classDefinition shouldStyle | - classSelection ifNil: [ ^false ]. - self switchIsComment ifTrue: [ ^false ]. - methodSelection - ifNotNil: [ - classDefinition := items - detect: [:ea | - ea isClassDefinition and: [ ea className = classSelection ] ] - ifNone: [ - (Smalltalk at: classSelection ifAbsent: [ Object ]) asClassDefinition ]. - shouldStyle := true ] - ifNil: [ - classDefinition := nil. - shouldStyle := categorySelection ~= self extensionsCategory ]. - aStyler - environment: self; - classOrMetaClass: (classDefinition ifNotNil: [ - SHMCClassDefinition - classDefinition: classDefinition - items: items - meta: switch = #class ]). - ^shouldStyle! Item was removed: - ----- Method: MCSnapshotBrowser>>bindingOf: (in category '*ShoutCore') ----- - bindingOf: aSymbol - - (Smalltalk bindingOf: aSymbol) ifNotNil: [ :binding | ^binding ]. - items do: [ :each | - (each isClassDefinition and: [ - each className = aSymbol ]) ifTrue: [ ^aSymbol -> each ] ]. - ^nil! Item was added: + ----- Method: Model>>hasBindingThatBeginsWith: (in category '*ShoutCore') ----- + hasBindingThatBeginsWith: aString + + ^ false! From jakob.reschke at student.hpi.de Wed May 6 10:26:22 2015 From: jakob.reschke at student.hpi.de (Jakob Reschke) Date: Wed May 6 10:26:46 2015 Subject: [squeak-dev] HTTP 404 for Trunk image download from squeak.org Message-ID: Hi, navigating the squeak.org downloads to Bleeding Edge Trunk Image & Changes (at Jenkins Build Server) http://build.squeak.org/job/SqueakTrunk/TrunkImage.zip results in HTTP 404. Tobias pointed out that the URL should rather be http://build.squeak.org/job/SqueakTrunk/lastSuccessfulBuild/artifact/target/TrunkImage.zip Would be nice if somebody could fix that link. :-) Best regards, Jakob From karlramberg at gmail.com Wed May 6 10:44:31 2015 From: karlramberg at gmail.com (karl ramberg) Date: Wed May 6 10:44:37 2015 Subject: [squeak-dev] Enhancement for pop up inform Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: DialogAtWorldCenter.1.cs Type: application/octet-stream Size: 3441 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150506/70c73ee7/DialogAtWorldCenter.1.obj From brasspen at gmail.com Wed May 6 12:15:34 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Wed May 6 12:15:36 2015 Subject: [squeak-dev] HTTP 404 for Trunk image download from squeak.org In-Reply-To: References: Message-ID: Mmmm... OK. I'll change that link later today. I think I'll change it to just build.squeak.org from http://build.squeak.org/job/SqueakTrunk/TrunkImage.zip. I'm sure Tobias is right, but I think I'm reasonable in assuming that things change more frequently on the build server than the homepage. And I would point out that that area is titled "Advanced," so I think I can be forgiven for assuming you know what you're looking for (i.e. a image with the word "Trunk" in it). I suppose that one might say I could have responded more quickly to this. To that I would suggest that in future people employ the webteam mailing list. It's infrequent use would draw my attention more readily. Chris On Wed, May 6, 2015 at 6:26 AM, Jakob Reschke wrote: > Hi, > > navigating the squeak.org downloads to > > Bleeding Edge Trunk Image & Changes (at Jenkins Build Server) > http://build.squeak.org/job/SqueakTrunk/TrunkImage.zip > > results in HTTP 404. > > Tobias pointed out that the URL should rather be > > http://build.squeak.org/job/SqueakTrunk/lastSuccessfulBuild/artifact/target/TrunkImage.zip > > Would be nice if somebody could fix that link. :-) > > Best regards, > Jakob > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150506/e01cd8f8/attachment.htm From nicolas.cellier.aka.nice at gmail.com Wed May 6 17:52:41 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed May 6 17:52:45 2015 Subject: [squeak-dev] Re: [Pharo-dev] Package comments In-Reply-To: <4C6F87A4-680E-4A42-87B2-B04B0B76EBAC@inria.fr> References: <1430757214049-4824353.post@n4.nabble.com> <25A268EF-AAA8-416C-94DF-29C2F3E634BA@inria.fr> <1430838892346-4824636.post@n4.nabble.com> <6046CD3A-1AB9-4248-A122-85A472E19AB6@inria.fr> <4C6F87A4-680E-4A42-87B2-B04B0B76EBAC@inria.fr> Message-ID: 2015-05-06 13:08 GMT+02:00 Marcus Denker : > > > On 06 May 2015, at 10:53, Christophe Demarey < > Christophe.Demarey@inria.fr> wrote: > > > > > > Le 5 mai 2015 ? 17:14, Kasper Osterbye a ?crit : > > > >> Marcus Denker-4 wrote > >>> Right now we do not have yet Package comments. > >>> > >>> But we should! > >>> > >>> MBInfo seems to be a private class of Versionner? > >>> > >>> For package comments we first need to evaluate the design space? > >>> e.g. where to store it in the image, how to store it in Monticello? > >> > >> OK - Makes sense. > >> > >> From my perspective, the key to getting this of the ground is to make > sure > >> such comments can be written and read in Nautilus. The package objects > used > >> in Nautilus are from "RPackage". > >> Thus, the problem, in my view reduces to: > >> a) How to make room in RPackage for a comment field (add one more IV) > >> b) How to integrate the storage of this field in connection with > Monticello > >> as Marcus writes. > > > > I don't think is the good way to do that. > > We are working on adding meta-data to packages. These meta-data includes > a package description (or comment) but also a lot of other data. > > You will not be able to store everything in rpackage inst. var. And of > course, there is also the problem that Monticello is not able to store > meta-data (e.g. STON files). > > For now, the best option is to use a PackageManifest. > > > > If you want to allow package comments in Nautilus, I would display the > content of the description method of the package manifest if available. > > > > Yes? this could be the easiest for now. > > Then as a second step, we add support to store resources in Monticello. > > Marcus > > > Adding metadata to MC cannot be very difficult, MC already carries plenty of metadata ;) Coordination with other dialects (squeak/gemstone/...) would be welcome, because i'm sure that every dialect would benefit from package comments, or already has package comments (vw along with many other properties). No long discussion required, if no consensus, just let Pharo lead. I remember that Bert has experimented adding a comment to PackageInfo, but I don't know in which state it did end up (MC-wise). Nicolas -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150506/123ac1a1/attachment.htm From commits at source.squeak.org Wed May 6 18:10:52 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 18:10:54 2015 Subject: [squeak-dev] The Trunk: Tests-ul.319.mcz Message-ID: Levente Uzonyi uploaded a new version of Tests to project The Trunk: http://source.squeak.org/trunk/Tests-ul.319.mcz ==================== Summary ==================== Name: Tests-ul.319 Author: ul Time: 6 May 2015, 6:03:36.809 pm UUID: d83e9ef7-c5df-441a-938e-a5ccb76827a7 Ancestors: Tests-ul.318 Actualized the list in DecompilerTests >> #decompilerFailures. Refactored DecompilerTests and DecompilerTestFailuresCollector: the class of the exception is noted and verified. =============== Diff against Tests-ul.318 =============== Item was changed: ----- Method: DecompilerTestFailuresCollector>>assert:description:resumable: (in category 'accessing') ----- + assert: aBoolean description: aString resumable: resumableBoolean + + | method | + aBoolean ifTrue: [ ^self ]. + method := thisContext sender home tempAt: 1. + self noteFailure: TestFailure for: method! - assert: aBoolean description: aString resumable: resumableBoolean - aBoolean ifFalse: - [failures isNil ifTrue: - [failures := OrderedCollection new]. - failures addLast: (thisContext sender home tempAt: 1) methodReference]! Item was changed: ----- Method: DecompilerTestFailuresCollector>>checkDecompileMethod: (in category 'utilities') ----- checkDecompileMethod: oldMethod + [ super checkDecompileMethod: oldMethod ] + on: Error + do: [ :error | self noteFailure: error class for: oldMethod ]! - [^super checkDecompileMethod: oldMethod] - on: SyntaxErrorNotification - do: [:ex| - self assert: false - description: 'syntax error' - resumable: true].! Item was changed: ----- Method: DecompilerTestFailuresCollector>>computeFailures (in category 'accessing') ----- computeFailures + + | tests | + failures := nil. + tests := (DecompilerTests organization listAtCategoryNamed: #tests) select: [ :s | + (s beginsWith: 'testDecompilerInClasses') ]. + CurrentReadOnlySourceFiles cacheDuring: [ + tests + do: [ :each | self perform: each ] + displayingProgress: 'Computing failures...' ]. + ^self decompilerFailures! - (DecompilerTests organization listAtCategoryNamed: #tests) do: - [:s| - (s beginsWith: 'testDecompilerInClasses') ifTrue: - [self perform: s]]. - ^failures! Item was added: + ----- Method: DecompilerTestFailuresCollector>>decompilerFailures (in category 'accessing') ----- + decompilerFailures + + failures ifNil: [ ^#() ]. + ^failures asArray sort: [ :a :b | + | r | + r := a first compare: b first caseSensitive: false. + r = 1 or: [ r = 2 and: [ + (a second compare: b second caseSensitive: false) <= 2 ] ] ]! Item was added: + ----- Method: DecompilerTestFailuresCollector>>errorClassForFailureFor:selector: (in category 'accessing') ----- + errorClassForFailureFor: class selector: selector + + ^nil! Item was added: + ----- Method: DecompilerTestFailuresCollector>>exceptionClassForFailureFor:selector: (in category 'utilities') ----- + exceptionClassForFailureFor: class selector: selector + + ^nil! Item was removed: - ----- Method: DecompilerTestFailuresCollector>>isFailure:sel: (in category 'accessing') ----- - isFailure: cls sel: selector - ^false! Item was added: + ----- Method: DecompilerTestFailuresCollector>>noteFailure:for: (in category 'utilities') ----- + noteFailure: exceptionClass for: method + + (failures ifNil: [ failures := OrderedCollection new ]) add: { + method methodClass name. + method selector. + exceptionClass name }! Item was changed: ----- Method: DecompilerTests>>decompileClassesSelect: (in category 'utilities') ----- decompileClassesSelect: aBlock CurrentReadOnlySourceFiles cacheDuring: [ + (self classNames select: aBlock) do: [ :cn | + | class | + (class := Smalltalk classNamed: cn) selectorsAndMethodsDo: [ :selector :method | + (self exceptionClassForFailureFor: class selector: selector) + ifNil: [ self checkDecompileMethod: method ] + ifNotNil: [ :exceptionClass | + self + should: [ self checkDecompileMethod: method ] + raise: exceptionClass ] ] ] ]! - (self classNames select: aBlock) do: - [:cn | | cls | - cls := Smalltalk globals at: cn. - cls selectorsAndMethodsDo: - [:selector :meth | - (self isFailure: cls sel: selector) ifFalse: - [self checkDecompileMethod: meth]]]]! Item was changed: ----- Method: DecompilerTests>>decompilerFailures (in category 'utilities') ----- decompilerFailures "Here is the list of failures: either a syntax error, a hard error or some failure to decompile correctly. + Collected via + DecompilerTestFailuresCollector new computeFailures." - Collected via - CurrentReadOnlySourceFiles cacheDuring: [ - (DecompilerTestFailuresCollector new computeFailures collect: - [:mr| { mr classSymbol. mr selector }]) asArray ]." + "class name, selector, error class name or nil" + ^#( (Behavior toolIconSelector: TestFailure) + (BrowserCommentTextMorph showPane SyntaxErrorNotification) + (ClassDescription replaceSilently:to: SyntaxErrorNotification) + (CodeHolder getSelectorAndSendQuery:to:with: SyntaxErrorNotification) + (Date printOn: TestFailure) + (DecompilerTests testDecompileUnreachableParameter Error) + (FontImporterTool fontFromFamily: SyntaxErrorNotification) "same-name block-local temps in optimized blocks" + (HttpUrl checkAuthorization:retry: TestFailure) + (LargeNegativeIntegerTest testReplaceFromToWithStartingAt SyntaxErrorNotification) "same-name block-local temps in optimized blocks" + (LargePositiveIntegerTest testReplaceFromToWithStartingAt SyntaxErrorNotification) "same-name block-local temps in optimized blocks" + (MailComposition breakLinesInMessage: SyntaxErrorNotification) + (MCConfigurationBrowser post SyntaxErrorNotification) + (MVCToolBuilder setLayout:in: SyntaxErrorNotification) "same-name block-local temps in optimized blocks" + (ParagraphEditor inOutdent:delta: SyntaxErrorNotification) + (PNGReadWriter copyPixelsGray: SyntaxErrorNotification) + (PointTest testNormal TestFailure) "fraction printing??" + (PointTest testTheta TestFailure) "fraction printing??" + (ScaledDecimalTest testConvertFromFraction SyntaxErrorNotification) "local/non-local temps" + (SHMCClassDefinition withAllSuperclassesDo: SyntaxErrorNotification) "same-name block-local temps in optimized blocks" + (StandardScriptingSystem holderWithAlphabet SyntaxErrorNotification) "same-name block-local temps in optimized blocks" + (SystemWindow convertAlignment SyntaxErrorNotification) + (TextEditor inOutdent:delta: SyntaxErrorNotification) + (TextURL actOnClickFor: TestFailure) + (TTContourConstruction segmentsDo: SyntaxErrorNotification) "Worth fixing; these two are mistaken conversion from a whileTrue: to a to:do: but the index is used outside the whileTrue:" + (TTFontReader processHorizontalMetricsTable:length: SyntaxErrorNotification))! - ^#( (Behavior toolIconSelector:) - (BrowserCommentTextMorph showPane) - (ClassDescription replaceSilently:to:) - (CodeHolder getSelectorAndSendQuery:to:with:) - (Date printOn:) - (DecompilerTests testDecompileUnreachableParameter) - (HttpUrl checkAuthorization:retry:) - (MCConfigurationBrowser post) - (MailComposition breakLinesInMessage:) - (MVCToolBuilder setLayout:in:) "same-name block-local temps in optimized blocks" - (ParagraphEditor inOutdent:delta:) - (PNGReadWriter copyPixelsGray:) - (PointTest testNormal) "fraction printing??" - (PointTest testTheta) "fraction printing??" - (ScaledDecimalTest testConvertFromFraction) "local/non-local temps" - (StandardScriptingSystem holderWithAlphabet) "same-name block-local temps in optimized blocks" - (SystemWindow convertAlignment) - (TextEditor inOutdent:delta:) - (TextURL actOnClickFor:) - (TTContourConstruction segmentsDo:) "Worth fixing; these two are mistaken conversion from a whileTrue: to a to:do: but the index is used outside the whileTrue:" - (TTFontReader processHorizontalMetricsTable:length:))! Item was added: + ----- Method: DecompilerTests>>exceptionClassForFailureFor:selector: (in category 'utilities') ----- + exceptionClassForFailureFor: class selector: selector + + ^self decompilerFailures + detect: [ :each | each first = class name and: [ each second = selector ] ] + ifFound: [ :each | each third ifNotNil: [ Smalltalk classNamed: each third ] ] + ifNone: [ nil ]! Item was removed: - ----- Method: DecompilerTests>>isFailure:sel: (in category 'utilities') ----- - isFailure: cls sel: selector - "self new isKnowProblem: PNMReaderWriter sel: #nextImage" - "#((PNMReadWriter nextImage)) includes: {PNMReadWriter - name asSymbol . #nextImage}." - ^(#(#DoIt #DoItIn:) includes: selector) - or: [self decompilerFailures includes: {cls name asSymbol. selector}]! From commits at source.squeak.org Wed May 6 18:11:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 18:11:32 2015 Subject: [squeak-dev] The Trunk: System-ul.737.mcz Message-ID: Levente Uzonyi uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-ul.737.mcz ==================== Summary ==================== Name: System-ul.737 Author: ul Time: 6 May 2015, 1:09:16.373 pm UUID: 80332b98-672e-40b3-a04b-8aee101654d0 Ancestors: System-kfr.736 #groupBy:having -> #groupBy: =============== Diff against System-kfr.736 =============== Item was changed: ----- Method: MessageTally>>rootPrintOn:total:totalTime:threshold: (in category 'printing') ----- rootPrintOn: aStream total: total totalTime: totalTime threshold: threshold | groups sons | sons := self sonsOver: threshold. + groups := sons groupBy: [ :aTally | aTally process ]. - groups := sons groupBy: [ :aTally | aTally process] having: [ :g | true]. groups keysAndValuesDo: [ :p :g | (reportOtherProcesses or: [ p notNil ]) ifTrue: [ aStream nextPutAll: '--------------------------------'; cr. aStream nextPutAll: 'Process: ', (p ifNil: [ 'other processes'] ifNotNil: [ p browserPrintString]); cr. aStream nextPutAll: '--------------------------------'; cr. g sort do:[:aSon | aSon treePrintOn: aStream tabs: OrderedCollection new thisTab: '' total: total totalTime: totalTime tallyExact: false orThreshold: threshold]]. ]! From commits at source.squeak.org Wed May 6 18:11:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 18:11:59 2015 Subject: [squeak-dev] The Trunk: KernelTests-ul.294.mcz Message-ID: Levente Uzonyi uploaded a new version of KernelTests to project The Trunk: http://source.squeak.org/trunk/KernelTests-ul.294.mcz ==================== Summary ==================== Name: KernelTests-ul.294 Author: ul Time: 6 May 2015, 1:08:44.167 pm UUID: 85c2194d-73c4-479d-8c4a-2c4663594c91 Ancestors: KernelTests-nice.293 #groupBy:having -> #groupBy: =============== Diff against KernelTests-nice.293 =============== Item was changed: ----- Method: CompiledMethodComparisonTest>>testHash (in category 'tests') ----- testHash | ai | ai := CompiledMethod allInstances. "We assume here that if two CompiledMethods are equal then they have the same size and header." ((ai + groupBy: [ :method | { method size. method header } ]) + replace: [ :each | each asArray ]) - groupBy: [ :method | { method size. method header } ] - having: [ :methods | true ]) - collect: [ :each | each asArray ]) do: [ :methods | 1 to: methods size do: [ :i | i to: methods size do: [ :j | (methods at: i) = (methods at: j) ifTrue: [ self assert: (methods at: i) hash equals: (methods at: i) hash ] ] ] ] displayingProgress: 'Testing hashes'. self assert: (ai collect: [ :cm | cm hash ] as: Set) size * 2 >= ai asSet size! From commits at source.squeak.org Wed May 6 18:11:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 18:12:03 2015 Subject: [squeak-dev] The Trunk: KernelTests-ul.295.mcz Message-ID: Levente Uzonyi uploaded a new version of KernelTests to project The Trunk: http://source.squeak.org/trunk/KernelTests-ul.295.mcz ==================== Summary ==================== Name: KernelTests-ul.295 Author: ul Time: 6 May 2015, 2:35:40.628 pm UUID: bd2d63b5-9819-4e81-b1e0-d14594c158ad Ancestors: KernelTests-ul.294 Fix: Dictionary DNU #replace: =============== Diff against KernelTests-ul.294 =============== Item was changed: ----- Method: CompiledMethodComparisonTest>>testHash (in category 'tests') ----- testHash | ai | ai := CompiledMethod allInstances. "We assume here that if two CompiledMethods are equal then they have the same size and header." + (ai groupBy: [ :method | { method size. method header } ]) values + replace: [ :each | each asArray ]; - ((ai - groupBy: [ :method | { method size. method header } ]) - replace: [ :each | each asArray ]) do: [ :methods | 1 to: methods size do: [ :i | i to: methods size do: [ :j | (methods at: i) = (methods at: j) ifTrue: [ self assert: (methods at: i) hash equals: (methods at: i) hash ] ] ] ] displayingProgress: 'Testing hashes'. self assert: (ai collect: [ :cm | cm hash ] as: Set) size * 2 >= ai asSet size! From commits at source.squeak.org Wed May 6 18:12:47 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 18:12:48 2015 Subject: [squeak-dev] The Trunk: EToys-ul.127.mcz Message-ID: Levente Uzonyi uploaded a new version of EToys to project The Trunk: http://source.squeak.org/trunk/EToys-ul.127.mcz ==================== Summary ==================== Name: EToys-ul.127 Author: ul Time: 6 May 2015, 1:09:47.616 pm UUID: c72942bd-8302-4555-8933-c69b3526ad2f Ancestors: EToys-kfr.126 #groupBy:having -> #groupBy: =============== Diff against EToys-kfr.126 =============== Item was changed: ----- Method: PasteUpMorph>>makeAllScriptEditorsReferToMasters (in category '*Etoys-world menu') ----- makeAllScriptEditorsReferToMasters "Ensure that all script editors refer to the first (by alphabetical externalName) Player among the list of siblings" + (self presenter allExtantPlayers groupBy: [ :p | p class ]) - (self presenter allExtantPlayers groupBy: [ :p | p class ] having: [ :p | true ]) do: [ :group | group first allScriptEditors ]! From eliot.miranda at gmail.com Wed May 6 18:21:12 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed May 6 18:21:18 2015 Subject: [squeak-dev] New Cog VMs available Message-ID: ... at http://www.mirandabanda.org/files/Cog/VM/VM.r3319. CogVM binaries as per VMMaker.oscog-eem.1288/r3319 Spur: Implement remembered table pruning via ref counts. The algorithm selectively tenures objects to reduce the remembered table, instead of merely tenuring everything. Be selective about remembering tenured objects; actually scan their contents before remembering willy-nilly. StackVM: Allow setting preemptionYields in the stack VM. Cogit: Use new register allocation in #== with V3 in order to limit register moves. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150506/4a0284e2/attachment.htm From leves at elte.hu Wed May 6 18:31:52 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 6 18:31:54 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi Eliot, The workaround is in the Trunk, so if you think that it may help, then please update your image (which creates the .spur versions), and recreate the .spur versions starting from at least Collections.spur-tfel.623 (or the .mcm which contains it). Levente On Tue, 5 May 2015, Levente Uzonyi wrote: > It seems to me that the tool which creates the .spur versions of the packages > is running in an updated non-spur Trunk image, and it somehow added its own > version of #isAlphaNumeric to Collections.spur-tfel.623. > > The method in Collections.spur-tfel.623 is: > > isAlphaNumeric > "Answer whether the receiver is a letter or a digit." > > self asInteger > 255 ifFalse: [ ^((ClassificationTable at: > self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. > ^self encodedCharSet isAlphaNumeric: self > > While in Collections-tfel.623 it is: > > isAlphaNumeric > "Answer whether the receiver is a letter or a digit." > > ^self encodedCharSet isAlphaNumeric: self > > The version which got patched is from Collections-ul.628 (which merges > Collections-ul.625): > > isAlphaNumeric > "Answer whether the receiver is a letter or a digit." > > value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) > bitAnd: AlphaNumericMask) > 0 ]. > ^self encodedCharSet isAlphaNumeric: self > > If I'm right, then we can work around the problem by updating the current > methods in Trunk to check whether the AlphaNumericMask is initialized (along > with DigitBit and LetterMask). Then update the image which creates, the .spur > versions, and finally recreate the Collections.spur packages starting from > tfel-623. > > Levente > > On Mon, 4 May 2015, Eliot Miranda wrote: > >> >> >> On Mon, May 4, 2015 at 1:55 PM, Levente Uzonyi wrote: >> I tried to update an old Spur image, and somehow Character >> >> #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by >> update.spur-ul.311) appeared in the image, while loading >> Collections.spur-tfel.623 from update.spur-mt.310. >> Assuming that the load order of the packages is untouched, I suspect >> that the method got merged in from the non-spur branch of >> Collections somehow. >> >> >> I think the multiple ancestry that one ends up with in Spur packages, e.g. >> that Collections.spur-abc.123 inherits from >> both?Collections.spur-xyz-122 and?Collections.abc-123, causes issues for >> the update merge.? I wonder whether that could be the cause? From commits at source.squeak.org Wed May 6 18:59:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 18:59:40 2015 Subject: [squeak-dev] The Inbox: EToys-kfr.127.mcz Message-ID: A new version of EToys was added to project The Inbox: http://source.squeak.org/inbox/EToys-kfr.127.mcz ==================== Summary ==================== Name: EToys-kfr.127 Author: kfr Time: 6 May 2015, 8:58:58.372 pm UUID: 78d9ce0c-9ee9-0c40-85cf-3fc29198913c Ancestors: EToys-kfr.126 Enhance color settings in PreferenceBrowser towards using more fillstyles for color and borders than just solid fill. =============== Diff against EToys-kfr.126 =============== Item was changed: PBPreferenceView subclass: #PBColorPreferenceView + instanceVariableNames: 'button' - instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Etoys-PreferenceBrowser'! Item was added: + ----- Method: PBColorPreferenceView>>adjustLabelColor (in category 'user interface') ----- + adjustLabelColor + | textColor | + (self preference preferenceValue luminance < 0.5) + ifTrue:[ textColor := Color white] + ifFalse:[ textColor := Color black]. + button allMorphsDo: [:m | (m isKindOf: StringMorph) ifTrue: [ m color: textColor]]. ! Item was added: + ----- Method: PBColorPreferenceView>>borderStyleMenu (in category 'user interface') ----- + borderStyleMenu + "Add border-style menu items" + + | aMenu | + aMenu := MenuMorph new defaultTarget: self. + + aMenu addStayUpItemSpecial. + aMenu add: 'border color...' translated target: self selector:#changeColor: argument: button. + aMenu addLine. + BorderStyle borderStyleChoices do: + [:sym | (aMenu borderStyleForSymbol: sym) + ifNotNil: + [aMenu add: sym translated target: self selector: #setBorderStyle: argument: sym]]. + ^aMenu openNear: ActiveHand bounds. + ! Item was added: + ----- Method: PBColorPreferenceView>>changeColor: (in category 'user interface') ----- + changeColor: aButton + aButton changeColor. + self preference preferenceValue: aButton fillStyle. + button label: self preference preferenceValue asString. + self adjustLabelColor ! Item was added: + ----- Method: PBColorPreferenceView>>colorMenuButton (in category 'user interface') ----- + colorMenuButton + | selector name | + name := self preference name. + (name includesSubstring: 'border' caseSensitive: false) + ifTrue: [ selector := #borderStyleMenu] + ifFalse:[ selector := #fillStyleMenu]. + button := SimpleButtonMorph new + label: self preference preferenceValue asString; + actionSelector: selector; + target: self. + name = #menuBorderColor + ifTrue:[ ^button borderColor: MenuMorph menuBorderColor; borderWidth: MenuMorph menuBorderWidth]. + name = #menuTitleBorderColor + ifTrue:[ ^button borderColor: MenuMorph menuTitleBorderColor; borderWidth: MenuMorph menuTitleBorderWidth]. + self adjustLabelColor. + ^button color: (self preference provider perform: (self preference selectors first)). + + + "UpdatingRectangleMorph new + target: self preference; + getSelector: #preferenceValue; + putSelector: #preferenceValue:; + extent: 22@22; + setBalloonText: 'click here to change the color' translated; + yourself."! Item was added: + ----- Method: PBColorPreferenceView>>fillStyleMenu (in category 'user interface') ----- + fillStyleMenu + "Add the items for changing the current fill style of the Morph" + | aMenu | + "self canHaveFillStyles ifFalse:[^aMenu add: 'change color...' translated target: self action: #changeColor]." + aMenu := MenuMorph new defaultTarget: self. + "self preference preferenceValue addFillStyleMenuItems: aMenu hand: nil from: self." + aMenu add: 'change color...' translated target: self selector:#changeColor: argument: button. + aMenu addLine. + aMenu add: 'solid fill' translated action: #useSolidFill. + "aMenu add: 'gradient fill' translated action: #useGradientFill. + aMenu add: 'bitmap fill' translated action: #useBitmapFill. + aMenu add: 'default fill' translated action: #useDefaultFill." + ^aMenu openNear: ActiveHand bounds. + ! Item was changed: ----- Method: PBColorPreferenceView>>representativeButtonWithColor:inPanel: (in category 'user interface') ----- representativeButtonWithColor: aColor inPanel: aPreferenceBrowser ^self horizontalPanel layoutInset: 2; color: aColor; cellInset: 20; cellPositioning: #center; addMorphBack: (StringMorph contents: self preference name); addMorphBack: self horizontalFiller; + addMorphBack: self colorMenuButton; - addMorphBack: self colorSwatch; yourself! Item was added: + ----- Method: PBColorPreferenceView>>setBorderStyle: (in category 'user interface') ----- + setBorderStyle: aBorderStyle + self preference name = #menuBorderColor + ifTrue: [button color: MenuMorph menuColor; + borderWidth: MenuMorph menuBorderWidth]. + self preference name = #menuTitleBorderColor + ifTrue: [button color: MenuMorph menuTitleColor; + borderWidth: MenuMorph menuTitleBorderWidth]. + self preference preferenceValue: aBorderStyle. + button label: self preference preferenceValue asString; + borderColor: aBorderStyle. + ! Item was added: + ----- Method: PBColorPreferenceView>>useGradientFill (in category 'user interface') ----- + useGradientFill + + "Make receiver use a solid fill style (e.g., a simple color)" + + + | color1 color2 fill | + self preference preferenceValue isGradientFill ifTrue:[^self]. "Already done" + color1 := Color white darker. + color2 := self preference preferenceValue asColor. + fill := GradientFillStyle ramp: {0.0 -> color1. 1.0 -> color2}. + fill origin: ActiveWorld topLeft. + fill direction: 0 @ ActiveWorld bounds extent y. + fill normal: ActiveWorld bounds extent x @ 0. + fill radial: false. + self preference preferenceValue: fill. + button label: self preference preferenceValue asString; + color: self preference preferenceValue! Item was added: + ----- Method: PBColorPreferenceView>>useSolidFill (in category 'user interface') ----- + useSolidFill + "Make receiver use a solid fill style (e.g., a simple color)" + self preference preferenceValue isSolidFill ifTrue:[^self]. "Already done" + self preference preferenceValue: self preference preferenceValue asColor. "Try minimizing changes" + + button label: self preference preferenceValue asString; + color: self preference preferenceValue + ! From lecteur at zogotounga.net Wed May 6 19:57:25 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Wed May 6 19:57:20 2015 Subject: [squeak-dev] [OT] Boeuf de Wei Message-ID: <554A7225.1050800@zogotounga.net> Hello, Here is a piece of music entirely composed (I mean written, not synthesized) in Squeak: http://www.zogotounga.net/zik/Boeuf%20de%20Wei%20.ogg Whether you enjoy it or not, it is kind of an achievement to me because muO has now reached a point where I could compose such a long and complex piece within a few hours, in a very straightforward and intuitive way, mostly by playing with morphs. Working with Squeak and Morphic has always been amazingly rewarding, fostering creativity without hindrance. So, on this occasion, let me say thanks to all Squeak developers, past, present and future, for this brilliant system ! I owe you much. Stef From nicolas.cellier.aka.nice at gmail.com Wed May 6 20:28:31 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed May 6 20:28:33 2015 Subject: [squeak-dev] The Trunk: KernelTests-ul.295.mcz In-Reply-To: <554a597f.4326340a.090f.7da7SMTPIN_ADDED_MISSING@mx.google.com> References: <554a597f.4326340a.090f.7da7SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Why not implement Dictionary replace:? 2015-05-06 20:11 GMT+02:00 : > Levente Uzonyi uploaded a new version of KernelTests to project The Trunk: > http://source.squeak.org/trunk/KernelTests-ul.295.mcz > > ==================== Summary ==================== > > Name: KernelTests-ul.295 > Author: ul > Time: 6 May 2015, 2:35:40.628 pm > UUID: bd2d63b5-9819-4e81-b1e0-d14594c158ad > Ancestors: KernelTests-ul.294 > > Fix: Dictionary DNU #replace: > > =============== Diff against KernelTests-ul.294 =============== > > Item was changed: > ----- Method: CompiledMethodComparisonTest>>testHash (in category > 'tests') ----- > testHash > > > | ai | > ai := CompiledMethod allInstances. > "We assume here that if two CompiledMethods are equal then they > have the same size and header." > + (ai groupBy: [ :method | { method size. method header } ]) values > + replace: [ :each | each asArray ]; > - ((ai > - groupBy: [ :method | { method size. method header } ]) > - replace: [ :each | each asArray ]) > do: [ :methods | > 1 to: methods size do: [ :i | > i to: methods size do: [ :j | > (methods at: i) = (methods at: j) > ifTrue: [ > self assert: (methods at: > i) hash equals: (methods at: i) hash ] ] ] ] > displayingProgress: 'Testing hashes'. > self assert: (ai collect: [ :cm | cm hash ] as: Set) size * 2 >= > ai asSet size! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150506/61b4d2ee/attachment.htm From herbertkoenig at gmx.net Wed May 6 20:40:18 2015 From: herbertkoenig at gmx.net (=?UTF-8?B?SGVyYmVydCBLw7ZuaWc=?=) Date: Wed May 6 20:40:21 2015 Subject: [squeak-dev] [OT] Boeuf de Wei In-Reply-To: <554A7225.1050800@zogotounga.net> References: <554A7225.1050800@zogotounga.net> Message-ID: <554A7C32.4040805@gmx.net> Hi Stef, is it written and also synthesized in Squeak? Not sure if I like it (wrong music for this moment) but it's impressive that this could be done by playing with morphs. I'd be very curious to watch a video about the composition process, or maybe read a writeup. Anyway, big thumbs up for this achievement and thanks for sharing! Cheers, Herbert Am 06.05.2015 um 21:57 schrieb St?phane Rollandin: > Hello, > > Here is a piece of music entirely composed (I mean written, not > synthesized) in Squeak: > > http://www.zogotounga.net/zik/Boeuf%20de%20Wei%20.ogg > > Whether you enjoy it or not, it is kind of an achievement to me > because muO has now reached a point where I could compose such a long > and complex piece within a few hours, in a very straightforward and > intuitive way, mostly by playing with morphs. > > Working with Squeak and Morphic has always been amazingly rewarding, > fostering creativity without hindrance. So, on this occasion, let me > say thanks to all Squeak developers, past, present and future, for > this brilliant system ! I owe you much. > > > Stef > From karlramberg at gmail.com Wed May 6 20:51:55 2015 From: karlramberg at gmail.com (karl ramberg) Date: Wed May 6 20:51:59 2015 Subject: [squeak-dev] [OT] Boeuf de Wei In-Reply-To: <554A7225.1050800@zogotounga.net> References: <554A7225.1050800@zogotounga.net> Message-ID: Very nice. I have browsed around your web site and listened to several of your music pieces. I am very impressed by what you have achieved with the software and the music you have made. Karl On Wed, May 6, 2015 at 9:57 PM, St?phane Rollandin wrote: > Hello, > > Here is a piece of music entirely composed (I mean written, not > synthesized) in Squeak: > > http://www.zogotounga.net/zik/Boeuf%20de%20Wei%20.ogg > > Whether you enjoy it or not, it is kind of an achievement to me because > muO has now reached a point where I could compose such a long and complex > piece within a few hours, in a very straightforward and intuitive way, > mostly by playing with morphs. > > Working with Squeak and Morphic has always been amazingly rewarding, > fostering creativity without hindrance. So, on this occasion, let me say > thanks to all Squeak developers, past, present and future, for this > brilliant system ! I owe you much. > > > Stef > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150506/0b9515f0/attachment.htm From lecteur at zogotounga.net Wed May 6 20:57:08 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Wed May 6 20:58:03 2015 Subject: [squeak-dev] [OT] Boeuf de Wei In-Reply-To: <554A7C32.4040805@gmx.net> References: <554A7225.1050800@zogotounga.net> <554A7C32.4040805@gmx.net> Message-ID: <554A8024.9060801@zogotounga.net> > is it written and also synthesized in Squeak? Written only. It's synthesized by a set of VST instruments hosted in Cantabile. > Not sure if I like it (wrong music for this moment) but it's impressive > that this could be done by playing with morphs. > > I'd be very curious to watch a video about the composition process, or > maybe read a writeup. Yes, I need to document muO editors. So far all written doc is a bunch of PDF documents you can get from http://www.zogotounga.net/comp/squeak/sqgeo.htm Best, Stef From commits at source.squeak.org Wed May 6 21:09:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 21:09:14 2015 Subject: [squeak-dev] The Inbox: Collections-nice.634.mcz Message-ID: Nicolas Cellier uploaded a new version of Collections to project The Inbox: http://source.squeak.org/inbox/Collections-nice.634.mcz ==================== Summary ==================== Name: Collections-nice.634 Author: nice Time: 6 May 2015, 11:08:55.927 pm UUID: 4d2e458d-25c3-4b58-8df0-858fd2a6e84e Ancestors: Collections-ul.633 Implement replace: in Dictionary =============== Diff against Collections-ul.633 =============== Item was added: + ----- Method: Dictionary>>replace: (in category 'enumerating') ----- + replace: aBlock + "Destructively replace the values in this Dictionary by applying aBlock, keeping the same keys. + Implementation note: subclasses not storing the key-value pairs as a list of Associations shall refine this method." + tally = 0 ifTrue: [ ^self]. + 1 to: array size do: [ :index | + (array at: index) ifNotNil: [ :element | + element value: (aBlock value: element value) ] ]! Item was added: + ----- Method: OrderedDictionary>>replace: (in category 'enumerating') ----- + replace: aBlock + "Like super, but iterate in order." + + order from: 1 to: tally do: [:each | each value: (aBlock value: each value)]! Item was added: + ----- Method: WeakKeyDictionary>>replace: (in category 'enumerating') ----- + replace: aBlock + "Like super except that aBlock shouldn't be invoked for any reclaimed (nil) key." + + tally = 0 ifTrue: [ ^self]. + 1 to: array size do: [ :index | + (array at: index) ifNotNil: [ :association | + association key ifNotNil: [ :key | "Don't let the key go away." + association value: (aBlock value: association value) ] ] ]! From commits at source.squeak.org Wed May 6 21:10:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 21:10:07 2015 Subject: [squeak-dev] The Inbox: CollectionsTests-nice.244.mcz Message-ID: Nicolas Cellier uploaded a new version of CollectionsTests to project The Inbox: http://source.squeak.org/inbox/CollectionsTests-nice.244.mcz ==================== Summary ==================== Name: CollectionsTests-nice.244 Author: nice Time: 6 May 2015, 11:09:57.558 pm UUID: 57fdcf9f-1ab0-45ee-873b-7117f527efbc Ancestors: CollectionsTests-mt.243 Test Dictionary replace: =============== Diff against CollectionsTests-mt.243 =============== Item was added: + ----- Method: DictionaryTest>>testReplace (in category 'testing') ----- + testReplace + | dict expected | + {Dictionary. IdentityDictionary} do: [:class | + dict := class newFromPairs:{ + #first. 1. + #second. 2. + #third. 3. + #fourth. 4. + #fifth. 5. + }. + dict replace: [:each | each asWords]. + expected := class newFromPairs:{ + #first. 'one'. + #second. 'two'. + #third. 'three'. + #fourth. 'four'. + #fifth. 'five'. + }. + self assert: dict = expected].! Item was added: + ----- Method: OrderedDictionaryTest>>testReplace (in category 'tests') ----- + testReplace + | dict expected k | + dict := OrderedDictionary newFromPairs:{ + #first. 13. + #second. 12. + #third. 11. + #fourth. 15. + #fifth. 14. + }. + k := 0. + dict replace: [:each | k := k + 1]. + expected := OrderedDictionary newFromPairs:{ + #first. 1. + #second. 2. + #third. 3. + #fourth. 4. + #fifth. 5. + }. + self assert: dict = expected.! From commits at source.squeak.org Wed May 6 21:20:56 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 21:20:57 2015 Subject: [squeak-dev] The Inbox: Kernel-nice.925.mcz Message-ID: Nicolas Cellier uploaded a new version of Kernel to project The Inbox: http://source.squeak.org/inbox/Kernel-nice.925.mcz ==================== Summary ==================== Name: Kernel-nice.925 Author: nice Time: 6 May 2015, 11:20:30.172 pm UUID: 17257512-fbd9-4aef-a2da-07287d89cb26 Ancestors: Kernel-mt.924 MethodDictionary must implement a different replace: because it's not association based unlike super AND because it should care of fushing some VM cache. =============== Diff against Kernel-mt.924 =============== Item was added: + ----- Method: MethodDictionary>>replace: (in category 'enumeration') ----- + replace: aBlock + tally = 0 ifTrue: [ ^self ]. + 1 to: self basicSize do: [ :i | + (self basicAt: i) ifNotNil: [ + (array at: i) flushCache. + array at: i put: (aBlock value: (array at: i)) ] ]! From commits at source.squeak.org Wed May 6 21:55:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 6 21:55:06 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150506215504.18057.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008301.html Name: Collections-ul.632 Ancestors: Collections-mt.631 Removed MutexForPicking and RandomForPicking from Collection along with the methods referencing them, because the accessor methods were private, and they were only intended to be used for shuffling. Separated #groupBy: from #groupBy:having:. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008302.html Name: Collections-ul.633 Ancestors: Collections-ul.632 Don't try to use Character's ClassificationTable when the new class variables are not initialized properly. This is a possible workaround to fix the Spur bootstrap. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008303.html Name: Traits-ul.305 Ancestors: Traits-mt.304 - cache the source files during recompilation ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008304.html Name: Monticello-mt.615 Ancestors: Monticello-eem.614 Some ShoutCore dependencies untangled. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008305.html Name: Morphic-mt.969 Ancestors: Morphic-cmm.968 Some ShoutCore dependencies untangled. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008306.html Name: ToolBuilder-Morphic-mt.147 Ancestors: ToolBuilder-Morphic-mt.146 Some ShoutCore dependencies untangled. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008307.html Name: ShoutCore-mt.51 Ancestors: ShoutCore-mt.50 Some ShoutCore dependencies untangled. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008308.html Name: Tests-ul.319 Ancestors: Tests-ul.318 Actualized the list in DecompilerTests >> #decompilerFailures. Refactored DecompilerTests and DecompilerTestFailuresCollector: the class of the exception is noted and verified. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008309.html Name: System-ul.737 Ancestors: System-kfr.736 #groupBy:having -> #groupBy: ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008310.html Name: KernelTests-ul.294 Ancestors: KernelTests-nice.293 #groupBy:having -> #groupBy: ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008311.html Name: KernelTests-ul.295 Ancestors: KernelTests-ul.294 Fix: Dictionary DNU #replace: ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008312.html Name: EToys-ul.127 Ancestors: EToys-kfr.126 #groupBy:having -> #groupBy: ============================================= From ma.chris.m at gmail.com Wed May 6 23:06:10 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Wed May 6 23:06:13 2015 Subject: [squeak-dev] 4.6 Release Update: Feature Freeze begins Monday, 5-May-2015 Message-ID: In today's Squeak board meeting we expressed a definitive interest in wrapping up this release so we can be free of the constant patching of the .spur branch and associated bootstrap conversions which Eliot has been graciously doing. Therefore, the board asks all contributors to withhold any further non-essential fixes and features after Sunday, May 10th. That's just four more days to finish any further feature contributions you may have for the 4.6 / 5.0 release. And, even until then, no high risk changes should be made in trunk. Starting next week we will need volunteers for the release-process duties like Release-Notes, Welcome workspaces, Preferences & Background, Image Setup, Website updates and a at least a few SqueakMap entry's for Squeak's signature packages. I'll see about making a new wiki page so we can organize around this. From ma.chris.m at gmail.com Wed May 6 23:06:49 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Wed May 6 23:06:50 2015 Subject: [squeak-dev] Re: 4.6 Release Update: Feature Freeze begins Monday, 11-May-2015 Message-ID: The freeze date is May 11th, not May 5th. On Wed, May 6, 2015 at 6:06 PM, Chris Muller wrote: > In today's Squeak board meeting we expressed a definitive interest in > wrapping up this release so we can be free of the constant patching of > the .spur branch and associated bootstrap conversions which Eliot has > been graciously doing. > > Therefore, the board asks all contributors to withhold any further > non-essential fixes and features after Sunday, May 10th. That's just > four more days to finish any further feature contributions you may > have for the 4.6 / 5.0 release. And, even until then, no high risk > changes should be made in trunk. > > Starting next week we will need volunteers for the release-process > duties like Release-Notes, Welcome workspaces, Preferences & > Background, Image Setup, Website updates and a at least a few > SqueakMap entry's for Squeak's signature packages. I'll see about > making a new wiki page so we can organize around this. From commits at source.squeak.org Thu May 7 01:18:25 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 01:18:26 2015 Subject: [squeak-dev] The Trunk: ShoutTests-ul.26.mcz Message-ID: Levente Uzonyi uploaded a new version of ShoutTests to project The Trunk: http://source.squeak.org/trunk/ShoutTests-ul.26.mcz ==================== Summary ==================== Name: ShoutTests-ul.26 Author: ul Time: 7 May 2015, 3:18:05.834 am UUID: 8830be7b-4069-46ab-810a-7fb3bd086564 Ancestors: ShoutTests-topa.25 Pass a String to SHParserST80, not a Text. =============== Diff against ShoutTests-topa.25 =============== Item was changed: ----- Method: SHParserST80Test>>verifyClass:selector: (in category 'utilities') ----- verifyClass: aBehavior selector: aSymbol | ranges position types errors | ranges := SHParserST80 new + rangesIn: (aBehavior sourceCodeAt: aSymbol) asString - rangesIn: (aBehavior sourceCodeAt: aSymbol) classOrMetaClass: aBehavior workspace: nil environment: nil. types := #(#default #invalid #excessCode #comment #unfinishedComment #'$' #character #integer #number #- #symbol #stringSymbol #literalArray #string #unfinishedString #assignment #ansiAssignment #literal #keyword #binary #unary #incompleteKeyword #incompleteBinary #incompleteUnary #undefinedKeyword #undefinedBinary #undefinedUnary #patternKeyword #patternBinary #patternUnary #self #super #true #false #nil #thisContext #return #patternArg #methodArg #blockPatternArg #blockArg #argument #blockArgColon #leftParenthesis #rightParenthesis #leftParenthesis1 #rightParenthesis1 #leftParenthesis2 #rightParenthesis2 #leftParenthesis3 #rightParenthesis3 #leftParenthesis4 #rightParenthesis4 #leftParenthesis5 #rightParenthesis5 #leftParenthesis6 #rightParenthesis6 #leftParenthesis7 #rightParenthesis7 #blockStart #blockEnd #blockStart1 #blockEnd1 #blockStart2 #blockEnd2 #blockStart3 #blockEnd3 #blockStart4 #blockEnd4 #blockStart5 #blockEnd5 #blockStart6 #blockEnd6 #blockStart7 #blockEnd7 #arrayStart #arrayEnd #arrayStart1 #arrayEnd1 #byteArrayStart #byteArrayEnd #byteArrayStart1 #byteArrayEnd1 #leftBrace #rightBrace #cascadeSeparator #statementSeparator #externalCallType #externalCallTypePointerIndicator #primitiveOrExternalCallStart #primitiveOrExternalCallEnd #methodTempBar #blockTempBar #blockArgsBar #primitive #externalFunctionCallingConvention #module #blockTempVar #blockPatternTempVar #instVar #workspaceVar #undefinedIdentifier #incompleteIdentifier #tempVar #patternTempVar #poolConstant #classVar #globalVar #pragmaKeyword #pragmaUnary #pragmaBinary) asIdentitySet. errors := #(#excessCode #unfinishedComment #unfinishedString) asIdentitySet. position := 0. ranges do: [ :each | self assert: 1 <= each length description: 'empty range'. self assert: position <= each start description: 'overlapping range'. self assert: each start <= each end description: 'empty range'. self assert: (types includes: each type) description: 'unknown type ' , each type. self deny: (errors includes: each type) description: 'error type ' , each type. position := each end ]! From lewis at mail.msen.com Thu May 7 02:35:01 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Thu May 7 02:35:02 2015 Subject: [squeak-dev] [OT] Boeuf de Wei In-Reply-To: <554A7225.1050800@zogotounga.net> References: <554A7225.1050800@zogotounga.net> Message-ID: <20150507023501.GA88175@shell.msen.com> On Wed, May 06, 2015 at 09:57:25PM +0200, St??phane Rollandin wrote: > Hello, > > Here is a piece of music entirely composed (I mean written, not > synthesized) in Squeak: > > http://www.zogotounga.net/zik/Boeuf%20de%20Wei%20.ogg > > Whether you enjoy it or not, it is kind of an achievement to me because > muO has now reached a point where I could compose such a long and > complex piece within a few hours, in a very straightforward and > intuitive way, mostly by playing with morphs. > > Working with Squeak and Morphic has always been amazingly rewarding, > fostering creativity without hindrance. So, on this occasion, let me say > thanks to all Squeak developers, past, present and future, for this > brilliant system ! I owe you much. Stef, Thank you for sharing this. There is a lot going on in your composition and I enjoyed listening to it. Dave From avalloud at smalltalk.comcastbiz.net Thu May 7 05:22:58 2015 From: avalloud at smalltalk.comcastbiz.net (Andres Valloud) Date: Thu May 7 05:23:20 2015 Subject: [squeak-dev] Camp Smalltalk Portland 2015 Message-ID: <554AF6B2.2020806@smalltalk.comcastbiz.net> An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150506/ece026dc/attachment.htm From commits at source.squeak.org Thu May 7 07:39:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 07:39:28 2015 Subject: [squeak-dev] The Trunk: Help-Squeak-TerseGuide-kfr.5.mcz Message-ID: Karl Ramberg uploaded a new version of Help-Squeak-TerseGuide to project The Trunk: http://source.squeak.org/trunk/Help-Squeak-TerseGuide-kfr.5.mcz ==================== Summary ==================== Name: Help-Squeak-TerseGuide-kfr.5 Author: kfr Time: 7 May 2015, 9:38:42.385 am UUID: 75a587af-6dbb-ee4b-b469-ad18259f34f8 Ancestors: Help-Squeak-TerseGuide-dhn.4 Expanded Rectangle guide a little =============== Diff against Help-Squeak-TerseGuide-dhn.4 =============== Item was changed: ----- Method: TerseGuideHelp class>>rectangle (in category 'pages') ----- rectangle ^HelpTopic title: 'Rectangle' contents: '"************************************************************************ * Rectangle: * ************************************************************************" Rectangle fromUser. + Rectangle origin: 0@0 corner: 100@100 "Origin and corners are absolute points" + Rectangle origin: 80@40 extent: 50@50 "Extent is added to origin" + Rectangle center: 40@50 extent: 30@20 "Center is half of extent" + Rectangle left: 1 right: 20 top: 1 bottom: 10 + + | col | + col := OrderedCollection new. + col add: (Rectangle center: 40@50 extent: 30@20). + col add: (Rectangle left: 1 right: 20 top: 1 bottom: 10). + Rectangle merging: col '! From karlramberg at gmail.com Thu May 7 12:01:53 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 7 12:01:57 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: I tried loading these changes manually but my image just crashes hard. If I try to add instance variable 'value' to Character I just get a debugger and no option to continue. Karl On Wed, May 6, 2015 at 8:31 PM, Levente Uzonyi wrote: > Hi Eliot, > > The workaround is in the Trunk, so if you think that it may help, then > please update your image (which creates the .spur versions), and recreate > the .spur versions starting from at least Collections.spur-tfel.623 (or the > .mcm which contains it). > > Levente > > > On Tue, 5 May 2015, Levente Uzonyi wrote: > > It seems to me that the tool which creates the .spur versions of the >> packages is running in an updated non-spur Trunk image, and it somehow >> added its own version of #isAlphaNumeric to Collections.spur-tfel.623. >> >> The method in Collections.spur-tfel.623 is: >> >> isAlphaNumeric >> "Answer whether the receiver is a letter or a digit." >> >> self asInteger > 255 ifFalse: [ ^((ClassificationTable >> at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. >> ^self encodedCharSet isAlphaNumeric: self >> >> While in Collections-tfel.623 it is: >> >> isAlphaNumeric >> "Answer whether the receiver is a letter or a digit." >> >> ^self encodedCharSet isAlphaNumeric: self >> >> The version which got patched is from Collections-ul.628 (which merges >> Collections-ul.625): >> >> isAlphaNumeric >> "Answer whether the receiver is a letter or a digit." >> >> value > 255 ifFalse: [ ^((ClassificationTable at: value + >> 1) bitAnd: AlphaNumericMask) > 0 ]. >> ^self encodedCharSet isAlphaNumeric: self >> >> If I'm right, then we can work around the problem by updating the current >> methods in Trunk to check whether the AlphaNumericMask is initialized >> (along with DigitBit and LetterMask). Then update the image which creates, >> the .spur versions, and finally recreate the Collections.spur packages >> starting from tfel-623. >> >> Levente >> >> On Mon, 4 May 2015, Eliot Miranda wrote: >> >> >>> >>> On Mon, May 4, 2015 at 1:55 PM, Levente Uzonyi wrote: >>> I tried to update an old Spur image, and somehow Character >> >>> #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by >>> update.spur-ul.311) appeared in the image, while loading >>> Collections.spur-tfel.623 from update.spur-mt.310. >>> Assuming that the load order of the packages is untouched, I >>> suspect that the method got merged in from the non-spur branch of >>> Collections somehow. >>> >>> >>> I think the multiple ancestry that one ends up with in Spur packages, >>> e.g. that Collections.spur-abc.123 inherits from >>> both Collections.spur-xyz-122 and Collections.abc-123, causes issues for >>> the update merge. I wonder whether that could be the cause? >> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/9197d8a7/attachment.htm From Das.Linux at gmx.de Thu May 7 12:03:11 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 7 12:03:15 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On 07.05.2015, at 14:01, karl ramberg wrote: > I tried loading these changes manually but my image just crashes hard. > > If I try to add instance variable 'value' to Character I just get a debugger and no option to continue. > > This may be because Character cannot have instance variables in Spur, IIRC? From karlramberg at gmail.com Thu May 7 12:12:13 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 7 12:12:15 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Then the Character changes must be changed Instance variable value was added in Collections.spur-ul.584.mcz it seems like On Thu, May 7, 2015 at 2:03 PM, Tobias Pape wrote: > > On 07.05.2015, at 14:01, karl ramberg wrote: > > > I tried loading these changes manually but my image just crashes hard. > > > > If I try to add instance variable 'value' to Character I just get a > debugger and no option to continue. > > > > > > This may be because Character cannot have instance variables in Spur, IIRC? > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/c6eddebe/attachment.htm From leves at elte.hu Thu May 7 13:56:06 2015 From: leves at elte.hu (Levente Uzonyi) Date: Thu May 7 13:56:10 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Before Spur Character has always had an instance variable named value. Characters are immediate in Spur, so the Character class has no instance variables there. If you browse Collections.spur-ul.584.mcz, you'll find the following definition: Magnitude immediateSubclass: #Character instanceVariableNames: '' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings' Levente On Thu, 7 May 2015, karl ramberg wrote: > Then the Character changes must be changedInstance variable value was added in?Collections.spur-ul.584.mcz it seems like > > On Thu, May 7, 2015 at 2:03 PM, Tobias Pape wrote: > > On 07.05.2015, at 14:01, karl ramberg wrote: > > > I tried loading these changes manually but my image just crashes hard. > > > > If I try to add instance variable 'value' to Character I just get a debugger and no option to continue. > > > > > > This may be because Character cannot have instance variables in Spur, IIRC? > > > > From nicolas.cellier.aka.nice at gmail.com Thu May 7 15:48:04 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Thu May 7 15:48:07 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Does that mean that current Spur update process is not robust to a further change of Character class definition? (like adding a class var for example) 2015-05-07 15:56 GMT+02:00 Levente Uzonyi : > Before Spur Character has always had an instance variable named value. > Characters are immediate in Spur, so the Character class has no instance > variables there. If you browse Collections.spur-ul.584.mcz, you'll find the > following definition: > > Magnitude immediateSubclass: #Character > instanceVariableNames: '' > classVariableNames: 'CharacterTable ClassificationTable > DigitValues LetterBits LowercaseBit UppercaseBit' > poolDictionaries: '' > category: 'Collections-Strings' > > > Levente > > On Thu, 7 May 2015, karl ramberg wrote: > > Then the Character changes must be changedInstance variable value was >> added in Collections.spur-ul.584.mcz it seems like >> >> On Thu, May 7, 2015 at 2:03 PM, Tobias Pape wrote: >> >> On 07.05.2015, at 14:01, karl ramberg >> wrote: >> >> > I tried loading these changes manually but my image just crashes >> hard. >> > >> > If I try to add instance variable 'value' to Character I just get >> a debugger and no option to continue. >> > >> > >> >> This may be because Character cannot have instance variables in >> Spur, IIRC? >> >> >> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/04ebb2ba/attachment.htm From commits at source.squeak.org Thu May 7 16:13:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 16:13:08 2015 Subject: [squeak-dev] The Trunk: Collections-ul.634.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.634.mcz ==================== Summary ==================== Name: Collections-ul.634 Author: ul Time: 7 May 2015, 5:02:54.386 pm UUID: c956dc83-2ef3-4df4-b1be-449dfb4be1bb Ancestors: Collections-ul.633 Revert the workaround from Collections-ul.633. =============== Diff against Collections-ul.633 =============== Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "Answer the receiver's matching lowercase Character." + value > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. - AlphaNumericMask ifNotNil: [ - value > 255 ifFalse: [ - | result | - (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 - ifTrue: [ ^self class value: result ] ] ]. ^self class value: (self encodedCharSet toLowercaseCode: value)! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "Answer the receiver's matching uppercase Character." + value > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. - AlphaNumericMask ifNotNil: [ - value > 255 ifFalse: [ - | result | - (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 - ifTrue: [ ^self class value: result ] ] ]. ^self class value: (self encodedCharSet toUppercaseCode: value)! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ]. - AlphaNumericMask ifNotNil: [ - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ] ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ]. - DigitBit ifNotNil: [ - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ] ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ]. - LetterMask ifNotNil: [ - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ] ]. ^self encodedCharSet isLetter: self! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ]. - AlphaNumericMask ifNotNil: [ - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ] ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ]. - AlphaNumericMask ifNotNil: [ - value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ] ]. ^self encodedCharSet isUppercase: self. ! From eliot.miranda at gmail.com Thu May 7 16:28:28 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 7 16:28:32 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Thu, May 7, 2015 at 8:48 AM, Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote: > Does that mean that current Spur update process is not robust to a further > change of Character class definition? (like adding a class var for example) > The Monticello package patcher is robust for class var and pool dictionary changes. I think the image bootstrap is too. But checking that it is is timeconsuming. That's one major motivation behind the feature freeze. I want to stop wasting cyclers on the bootstrap and progress to the full release where we're free to modify definitions as we see fit. > > 2015-05-07 15:56 GMT+02:00 Levente Uzonyi : > >> Before Spur Character has always had an instance variable named value. >> Characters are immediate in Spur, so the Character class has no instance >> variables there. If you browse Collections.spur-ul.584.mcz, you'll find the >> following definition: >> >> Magnitude immediateSubclass: #Character >> instanceVariableNames: '' >> classVariableNames: 'CharacterTable ClassificationTable >> DigitValues LetterBits LowercaseBit UppercaseBit' >> poolDictionaries: '' >> category: 'Collections-Strings' >> >> >> Levente >> >> On Thu, 7 May 2015, karl ramberg wrote: >> >> Then the Character changes must be changedInstance variable value was >>> added in Collections.spur-ul.584.mcz it seems like >>> >>> On Thu, May 7, 2015 at 2:03 PM, Tobias Pape wrote: >>> >>> On 07.05.2015, at 14:01, karl ramberg >>> wrote: >>> >>> > I tried loading these changes manually but my image just crashes >>> hard. >>> > >>> > If I try to add instance variable 'value' to Character I just >>> get a debugger and no option to continue. >>> > >>> > >>> >>> This may be because Character cannot have instance variables in >>> Spur, IIRC? >>> >>> >>> >>> >> >> >> > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/e14cec0b/attachment.htm From eliot.miranda at gmail.com Thu May 7 16:34:33 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 7 16:34:36 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi Levente, On Mon, May 4, 2015 at 1:55 PM, Levente Uzonyi wrote: > I tried to update an old Spur image, and somehow Character >> > #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by > update.spur-ul.311) appeared in the image, while loading > Collections.spur-tfel.623 from update.spur-mt.310. > Assuming that the load order of the packages is untouched, I suspect that > the method got merged in from the non-spur branch of Collections somehow. Yes. I see this. The bootstrap is clearly broken. I'll look at this right away. > > > Levente > > > On Mon, 4 May 2015, Levente Uzonyi wrote: > > On Mon, 4 May 2015, Eliot Miranda wrote: >> >> This breaks my image, dumping it into the emergency evaluator, I *think* >>> because the new LetterMask, AlphaNumbericMask and DigitBit variables are >>> not handledf correctly by the Spur bootstrap. Sigh. So for >>> those of you using Spur please *don't* update until I've fixed the >>> bootstrap. >>> You know, by /not/ releasing, we are delaying because now I am fixing >>> the bootstrap to keep up with development, instead of us having released, >>> and being able to freely commit on Spur. We are now wasting >>> cycles. At least I am. >>> >> >> Multilingual-ul.209 should be loaded before Collections-ul.627, and only >> then should Collections-ul.628 be loaded. >> >> In the regular Trunk, I added an update map which loads >> Multilingual-ul.209 and Collections-ul.627 first. (Multilingual was before >> Collections in the map, so the load order was already guaranteed). >> >> Levente >> >> >>> On Mon, May 4, 2015 at 10:46 AM, wrote: >>> Eliot Miranda uploaded a new version of Collections to project The >>> Trunk: >>> http://source.squeak.org/trunk/Collections.spur-nice.622.mcz >>> >>> ==================== Summary ==================== >>> >>> Name: Collections.spur-nice.622 >>> Author: eem >>> Time: 4 May 2015, 10:45:05.244 am >>> UUID: 02450614-82e9-4d33-95fd-3fede06790d2 >>> Ancestors: Collections-nice.622, Collections.spur-mt.621 >>> >>> Collections-nice.622 patched for Spur by >>> SpurBootstrapMonticelloPackagePatcher Cog-eem.262 >>> >>> #toBraceStack: is not used for compiling { } for so long that it's >>> really time to get rid of it. >>> >>> Symbol>>numArgs: does not need to copy self into a temp var. >>> >>> =============== Diff against Collections-nice.622 =============== >>> >>> Item was changed: >>> ----- Method: Array>>elementsExchangeIdentityWith: (in category >>> 'converting') ----- >>> elementsExchangeIdentityWith: otherArray >>> + "This primitive performs a bulk mutation, causing all >>> pointers to the elements of the >>> + receiver to be replaced by pointers to the corresponding >>> elements of otherArray. >>> + At the same time, all pointers to the elements of >>> otherArray are replaced by >>> + pointers to the corresponding elements of this array. >>> The identityHashes remain >>> + with the pointers rather than with the objects so that >>> objects in hashed structures >>> + should still be properly indexed after the mutation." >>> - "This primitive performs a bulk mutation, causing all >>> pointers to the elements of this array to be replaced by pointers to the >>> corresponding elements of otherArray. At the same time, all >>> pointers to the elements of otherArray are replaced by pointers to >>> the corresponding elements of this array. The identityHashes remain with >>> the pointers rather than with the objects so that >>> objects in hashed structures should still be properly indexed >>> after the mutation." >>> >>> + >>> + ec == #'bad receiver' ifTrue: >>> + [^self error: 'receiver must be of class Array']. >>> + ec == #'bad argument' ifTrue: >>> + [^self error: (otherArray class == Array >>> + ifTrue: ['arg must >>> be of class Array'] >>> + ifFalse: >>> ['receiver and argument must have the same size'])]. >>> + ec == #'inappropriate operation' ifTrue: >>> + [^self error: 'can''t become immediates such as >>> SmallIntegers or Characters']. >>> + ec == #'no modification' ifTrue: >>> + [^self error: 'can''t become immutable objects']. >>> + ec == #'object is pinned' ifTrue: >>> + [^self error: 'can''t become pinned objects']. >>> + ec == #'insufficient object memory' ifTrue: >>> + [Smalltalk garbageCollect < 1048576 ifTrue: >>> + [Smalltalk growMemoryByAtLeast: 1048576]. >>> + ^self elementsExchangeIdentityWith: otherArray]. >>> + self primitiveFailed! >>> - >>> - otherArray class == Array ifFalse: [^ self error: 'arg >>> must be array']. >>> - self size = otherArray size ifFalse: [^ self error: >>> 'arrays must be same size']. >>> - (self anySatisfy: [:obj | obj class == SmallInteger]) >>> ifTrue: [^ self error: 'can''t become SmallIntegers']. >>> - (otherArray anySatisfy: [:obj | obj class == >>> SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. >>> - self with: otherArray do:[:a :b| a == b ifTrue:[^self >>> error:'can''t become yourself']]. >>> - >>> - "Must have failed because not enough space in forwarding >>> table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). >>> Do GC and try again only once" >>> - (Smalltalk bytesLeft: true) = Smalltalk >>> primitiveGarbageCollect >>> - ifTrue: [^ self primitiveFailed]. >>> - ^ self elementsExchangeIdentityWith: otherArray! >>> >>> Item was changed: >>> ----- Method: Array>>elementsForwardIdentityTo: (in category >>> 'converting') ----- >>> elementsForwardIdentityTo: otherArray >>> + "This primitive performs a bulk mutation, causing all >>> pointers to the elements of the >>> + receiver to be replaced by pointers to the corresponding >>> elements of otherArray. >>> + The identityHashes remain with the pointers rather than >>> with the objects so that >>> + the objects in this array should still be properly >>> indexed in any existing hashed >>> + structures after the mutation." >>> + >>> - "This primitive performs a bulk mutation, causing all >>> pointers to the elements of this array to be replaced by pointers to the >>> corresponding elements of otherArray. The identityHashes >>> remain with the pointers rather than with the objects so that the >>> objects in this array should still be properly indexed in any existing >>> hashed structures after the mutation." >>> - >>> self primitiveFailed! >>> >>> Item was changed: >>> ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in >>> category 'converting') ----- >>> elementsForwardIdentityTo: otherArray copyHash: copyHash >>> + "This primitive performs a bulk mutation, causing all >>> pointers to the elements of the >>> + receiver to be replaced by pointers to the corresponding >>> elements of otherArray. >>> + If copyHash is true, the identityHashes remain with the >>> pointers rather than with the >>> + objects so that the objects in the receiver should still >>> be properly indexed in any >>> + existing hashed structures after the mutation. If >>> copyHash is false, then the hashes >>> + of the objects in otherArray remain unchanged. If you >>> know what you're doing this >>> + may indeed be what you want." >>> + >>> - "This primitive performs a bulk mutation, causing all >>> pointers to the elements of this array to be replaced by pointers to the >>> corresponding elements of otherArray. The identityHashes >>> remain with the pointers rather than with the objects so that the >>> objects in this array should still be properly indexed in any existing >>> hashed structures after the mutation." >>> - >>> self primitiveFailed! >>> >>> Item was changed: >>> ==== ERROR === >>> >>> Error: Unrecognized class type >>> >>> 4 May 2015 5:47:40.493 pm >>> >>> VM: unix - a SmalltalkImage >>> Image: Squeak3.11alpha [latest update: #8824] >>> >>> SecurityManager state: >>> Restricted: false >>> FileAccess: true >>> SocketAccess: true >>> Working Dir /home/squeaksource >>> Trusted Dir /home/squeaksource/secure >>> Untrusted Dir /home/squeaksource/My Squeak >>> >>> MCClassDefinition(Object)>>error: >>> Receiver: a MCClassDefinition(Character) >>> Arguments and temporary variables: >>> aString: 'Unrecognized class type' >>> Receiver's instance variables: >>> name: #Character >>> superclassName: #Magnitude >>> variables: an OrderedCollection(a >>> MCClassVariableDefinition(CharacterTable) a M...etc... >>> category: 'Collections-Strings' >>> type: #immediate >>> comment: 'I represent a character by >>> storing its associated Unicode as an unsig...etc... >>> commentStamp: 'eem 8/12/2014 14:53' >>> traitComposition: nil >>> classTraitComposition: nil >>> >>> MCClassDefinition>>kindOfSubclass >>> Receiver: a MCClassDefinition(Character) >>> Arguments and temporary variables: >>> >>> Receiver's instance variables: >>> name: #Character >>> superclassName: #Magnitude >>> variables: an OrderedCollection(a >>> MCClassVariableDefinition(CharacterTable) a M...etc... >>> category: 'Collections-Strings' >>> type: #immediate >>> comment: 'I represent a character by >>> storing its associated Unicode as an unsig...etc... >>> commentStamp: 'eem 8/12/2014 14:53' >>> traitComposition: nil >>> classTraitComposition: nil >>> >>> MCClassDefinition>>printDefinitionOn: >>> Receiver: a MCClassDefinition(Character) >>> Arguments and temporary variables: >>> stream: a WriteStream >>> Receiver's instance variables: >>> name: #Character >>> superclassName: #Magnitude >>> variables: an OrderedCollection(a >>> MCClassVariableDefinition(CharacterTable) a M...etc... >>> category: 'Collections-Strings' >>> type: #immediate >>> comment: 'I represent a character by >>> storing its associated Unicode as an unsig...etc... >>> commentStamp: 'eem 8/12/2014 14:53' >>> traitComposition: nil >>> classTraitComposition: nil >>> >>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>> Receiver: a MCDiffyTextWriter >>> Arguments and temporary variables: >>> definition: a WriteStream >>> s: a MCClassDefinition(Character) >>> Receiver's instance variables: >>> stream: a WriteStream >>> initStream: nil >>> >>> >>> --- The full stack --- >>> MCClassDefinition(Object)>>error: >>> MCClassDefinition>>kindOfSubclass >>> MCClassDefinition>>printDefinitionOn: >>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >>> String class(SequenceableCollection class)>>new:streamContents: >>> String class(SequenceableCollection class)>>streamContents: >>> MCDiffyTextWriter(MCTextWriter)>>chunkContents: >>> MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>> MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: >>> MCClassDefinition>>accept: >>> [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>> String class(SequenceableCollection class)>>new:streamContents: >>> String class(SequenceableCollection class)>>streamContents: >>> MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>> MCDiffyTextWriter>>writePatchFrom:to: >>> MCDiffyTextWriter>>writeModification: >>> [] in MCDiffyTextWriter>>writePatch: >>> SortedCollection(OrderedCollection)>>do: >>> MCDiffyTextWriter>>writePatch: >>> SSDiffyTextWriter>>writePatch: >>> [] in SSDiffyTextWriter>>writeVersion:for: >>> BlockClosure>>on:do: >>> SSDiffyTextWriter>>writeVersion:for: >>> [] in SSEMailSubscription>>versionAdded:to: >>> BlockClosure>>on:do: >>> SSEMailSubscription>>versionAdded:to: >>> [] in [] in SSProject>>versionAdded: >>> [] in BlockClosure>>newProcess >>> >>> >>> >>> >>> -- >>> best,Eliot >>> >>> > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/f166e650/attachment-0001.htm From tim.olson.mail at gmail.com Thu May 7 16:48:10 2015 From: tim.olson.mail at gmail.com (Tim Olson) Date: Thu May 7 16:48:45 2015 Subject: [squeak-dev] Problem updating image to latest Message-ID: When I try to update my image, I eventually get a debugger window with various different DNU situations triggered by a displayWorld call. In each case, the receiver that triggers the DNU is not the value it should be (or that the debugger says the value is). For example, the top of the debugger stack: SmallInteger(Object) >> doesNotUnderstand: #isEmptyOrNil PluggableListMorphOfMany(PluggableListMorph) >> hasFilter where: hasFilter ^ lastKeystrokes isEmptyOrNil not the debugger in the context of hasFilter says that lastKeystrokes is an empty ByteString, but when I click on self for the SmallInteger DNU, it says that the receiver is a SmallInteger 0. This happened during the update at ?Processing update-ul.303.mcm? / ?Reshaping Morphic-mt.824?, but I?ve also seen it fail more catastrophically later on when a message send to BorderStyle class actually sends width:color: to the ByteString #simple, causing every window to eventually be drawn with the I am running with the following Image and VM config: Image ----- /Users/tim/Programming/Squeak4/Squeak4.5.image Squeak4.4 latest update: #14301 Current Change Set: Morphic-mt.824 Image format 6505 (32 bit) Virtual Machine --------------- /Users/tim/Programming/Squeak4/Cog.app/Contents/MacOS/Squeak Croquet Closure Cog VM [CoInterpreterPrimitives VMMaker.oscog-eem.1288] Squeak Cog 4.0.3319 Mac OS X built on May 6 2015 15:44:21 UTC Compiler: 4.2.1 (Apple Inc. build 5666) (dot 3) platform sources revision VM: r3319 http://www.squeakvm.org/svn/squeak/branches/Cog Date: 2015-05-05 22:28:32 -0700 Plugins: r3275 http://squeakvm.org/svn/squeak/trunk/platforms/Cross/plugins CoInterpreter VMMaker.oscog-eem.1288 uuid: 909625f0-4d63-4a3b-84e1-1f2753923d7e May 6 2015 StackToRegisterMappingCogit VMMaker.oscog-eem.1288 uuid: 909625f0-4d63-4a3b-84e1-1f2753923d7e May 6 2015 I downloaded the latest VM just today, but this was failing on the previous Cog VM, as well. Also, my original image seems to run fine with both VMs, so it appears to be something in the update process that is causing the problem. Any ideas on how to debug this further? ? tim From eliot.miranda at gmail.com Thu May 7 17:10:07 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 7 17:10:10 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi Levente, On Thu, May 7, 2015 at 9:34 AM, Eliot Miranda wrote: > Hi Levente, > > On Mon, May 4, 2015 at 1:55 PM, Levente Uzonyi wrote: > >> I tried to update an old Spur image, and somehow Character >> >> #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by >> update.spur-ul.311) appeared in the image, while loading >> Collections.spur-tfel.623 from update.spur-mt.310. >> Assuming that the load order of the packages is untouched, I suspect that >> the method got merged in from the non-spur branch of Collections somehow. > > > Yes. I see this. The bootstrap is clearly broken. I'll look at this > right away. > Ah, MCMethodDefinition class>>className: classString classIsMeta: metaBoolean selector: selectorString category: catString timeStamp: timeString source: sourceString ^ self instanceLike: (self new initializeWithClassName: classString classIsMeta: metaBoolean selector: selectorString category: catString timeStamp: timeString source: sourceString) this will share definitions, and given that I'm modifying definitions as part of the patch process I guess I could end up modifying a definition that was inadvertently shared. I'm rewriting to avoid use of shared instances. i.e. I will use MCMethodDefinition new initializeWithClassName ... instead of MCMethodDefinition className: ... > >> >> >> Levente >> >> >> On Mon, 4 May 2015, Levente Uzonyi wrote: >> >> On Mon, 4 May 2015, Eliot Miranda wrote: >>> >>> This breaks my image, dumping it into the emergency evaluator, I >>>> *think* because the new LetterMask, AlphaNumbericMask and DigitBit >>>> variables are not handledf correctly by the Spur bootstrap. Sigh. So for >>>> those of you using Spur please *don't* update until I've fixed the >>>> bootstrap. >>>> You know, by /not/ releasing, we are delaying because now I am fixing >>>> the bootstrap to keep up with development, instead of us having released, >>>> and being able to freely commit on Spur. We are now wasting >>>> cycles. At least I am. >>>> >>> >>> Multilingual-ul.209 should be loaded before Collections-ul.627, and only >>> then should Collections-ul.628 be loaded. >>> >>> In the regular Trunk, I added an update map which loads >>> Multilingual-ul.209 and Collections-ul.627 first. (Multilingual was before >>> Collections in the map, so the load order was already guaranteed). >>> >>> Levente >>> >>> >>>> On Mon, May 4, 2015 at 10:46 AM, wrote: >>>> Eliot Miranda uploaded a new version of Collections to project >>>> The Trunk: >>>> http://source.squeak.org/trunk/Collections.spur-nice.622.mcz >>>> >>>> ==================== Summary ==================== >>>> >>>> Name: Collections.spur-nice.622 >>>> Author: eem >>>> Time: 4 May 2015, 10:45:05.244 am >>>> UUID: 02450614-82e9-4d33-95fd-3fede06790d2 >>>> Ancestors: Collections-nice.622, Collections.spur-mt.621 >>>> >>>> Collections-nice.622 patched for Spur by >>>> SpurBootstrapMonticelloPackagePatcher Cog-eem.262 >>>> >>>> #toBraceStack: is not used for compiling { } for so long that >>>> it's really time to get rid of it. >>>> >>>> Symbol>>numArgs: does not need to copy self into a temp var. >>>> >>>> =============== Diff against Collections-nice.622 =============== >>>> >>>> Item was changed: >>>> ----- Method: Array>>elementsExchangeIdentityWith: (in category >>>> 'converting') ----- >>>> elementsExchangeIdentityWith: otherArray >>>> + "This primitive performs a bulk mutation, causing all >>>> pointers to the elements of the >>>> + receiver to be replaced by pointers to the corresponding >>>> elements of otherArray. >>>> + At the same time, all pointers to the elements of >>>> otherArray are replaced by >>>> + pointers to the corresponding elements of this array. >>>> The identityHashes remain >>>> + with the pointers rather than with the objects so that >>>> objects in hashed structures >>>> + should still be properly indexed after the mutation." >>>> - "This primitive performs a bulk mutation, causing all >>>> pointers to the elements of this array to be replaced by pointers to the >>>> corresponding elements of otherArray. At the same time, all >>>> pointers to the elements of otherArray are replaced by pointers >>>> to the corresponding elements of this array. The identityHashes remain >>>> with the pointers rather than with the objects so that >>>> objects in hashed structures should still be properly indexed >>>> after the mutation." >>>> >>>> + >>>> + ec == #'bad receiver' ifTrue: >>>> + [^self error: 'receiver must be of class Array']. >>>> + ec == #'bad argument' ifTrue: >>>> + [^self error: (otherArray class == Array >>>> + ifTrue: ['arg >>>> must be of class Array'] >>>> + ifFalse: >>>> ['receiver and argument must have the same size'])]. >>>> + ec == #'inappropriate operation' ifTrue: >>>> + [^self error: 'can''t become immediates such as >>>> SmallIntegers or Characters']. >>>> + ec == #'no modification' ifTrue: >>>> + [^self error: 'can''t become immutable objects']. >>>> + ec == #'object is pinned' ifTrue: >>>> + [^self error: 'can''t become pinned objects']. >>>> + ec == #'insufficient object memory' ifTrue: >>>> + [Smalltalk garbageCollect < 1048576 ifTrue: >>>> + [Smalltalk growMemoryByAtLeast: 1048576]. >>>> + ^self elementsExchangeIdentityWith: otherArray]. >>>> + self primitiveFailed! >>>> - >>>> - otherArray class == Array ifFalse: [^ self error: 'arg >>>> must be array']. >>>> - self size = otherArray size ifFalse: [^ self error: >>>> 'arrays must be same size']. >>>> - (self anySatisfy: [:obj | obj class == SmallInteger]) >>>> ifTrue: [^ self error: 'can''t become SmallIntegers']. >>>> - (otherArray anySatisfy: [:obj | obj class == >>>> SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. >>>> - self with: otherArray do:[:a :b| a == b ifTrue:[^self >>>> error:'can''t become yourself']]. >>>> - >>>> - "Must have failed because not enough space in forwarding >>>> table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). >>>> Do GC and try again only once" >>>> - (Smalltalk bytesLeft: true) = Smalltalk >>>> primitiveGarbageCollect >>>> - ifTrue: [^ self primitiveFailed]. >>>> - ^ self elementsExchangeIdentityWith: otherArray! >>>> >>>> Item was changed: >>>> ----- Method: Array>>elementsForwardIdentityTo: (in category >>>> 'converting') ----- >>>> elementsForwardIdentityTo: otherArray >>>> + "This primitive performs a bulk mutation, causing all >>>> pointers to the elements of the >>>> + receiver to be replaced by pointers to the corresponding >>>> elements of otherArray. >>>> + The identityHashes remain with the pointers rather than >>>> with the objects so that >>>> + the objects in this array should still be properly >>>> indexed in any existing hashed >>>> + structures after the mutation." >>>> + >>>> - "This primitive performs a bulk mutation, causing all >>>> pointers to the elements of this array to be replaced by pointers to the >>>> corresponding elements of otherArray. The identityHashes >>>> remain with the pointers rather than with the objects so that the >>>> objects in this array should still be properly indexed in any existing >>>> hashed structures after the mutation." >>>> - >>>> self primitiveFailed! >>>> >>>> Item was changed: >>>> ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in >>>> category 'converting') ----- >>>> elementsForwardIdentityTo: otherArray copyHash: copyHash >>>> + "This primitive performs a bulk mutation, causing all >>>> pointers to the elements of the >>>> + receiver to be replaced by pointers to the corresponding >>>> elements of otherArray. >>>> + If copyHash is true, the identityHashes remain with the >>>> pointers rather than with the >>>> + objects so that the objects in the receiver should still >>>> be properly indexed in any >>>> + existing hashed structures after the mutation. If >>>> copyHash is false, then the hashes >>>> + of the objects in otherArray remain unchanged. If you >>>> know what you're doing this >>>> + may indeed be what you want." >>>> + >>>> - "This primitive performs a bulk mutation, causing all >>>> pointers to the elements of this array to be replaced by pointers to the >>>> corresponding elements of otherArray. The identityHashes >>>> remain with the pointers rather than with the objects so that the >>>> objects in this array should still be properly indexed in any existing >>>> hashed structures after the mutation." >>>> - >>>> self primitiveFailed! >>>> >>>> Item was changed: >>>> ==== ERROR === >>>> >>>> Error: Unrecognized class type >>>> >>>> 4 May 2015 5:47:40.493 pm >>>> >>>> VM: unix - a SmalltalkImage >>>> Image: Squeak3.11alpha [latest update: #8824] >>>> >>>> SecurityManager state: >>>> Restricted: false >>>> FileAccess: true >>>> SocketAccess: true >>>> Working Dir /home/squeaksource >>>> Trusted Dir /home/squeaksource/secure >>>> Untrusted Dir /home/squeaksource/My Squeak >>>> >>>> MCClassDefinition(Object)>>error: >>>> Receiver: a MCClassDefinition(Character) >>>> Arguments and temporary variables: >>>> aString: 'Unrecognized class type' >>>> Receiver's instance variables: >>>> name: #Character >>>> superclassName: #Magnitude >>>> variables: an OrderedCollection(a >>>> MCClassVariableDefinition(CharacterTable) a M...etc... >>>> category: 'Collections-Strings' >>>> type: #immediate >>>> comment: 'I represent a character by >>>> storing its associated Unicode as an unsig...etc... >>>> commentStamp: 'eem 8/12/2014 14:53' >>>> traitComposition: nil >>>> classTraitComposition: nil >>>> >>>> MCClassDefinition>>kindOfSubclass >>>> Receiver: a MCClassDefinition(Character) >>>> Arguments and temporary variables: >>>> >>>> Receiver's instance variables: >>>> name: #Character >>>> superclassName: #Magnitude >>>> variables: an OrderedCollection(a >>>> MCClassVariableDefinition(CharacterTable) a M...etc... >>>> category: 'Collections-Strings' >>>> type: #immediate >>>> comment: 'I represent a character by >>>> storing its associated Unicode as an unsig...etc... >>>> commentStamp: 'eem 8/12/2014 14:53' >>>> traitComposition: nil >>>> classTraitComposition: nil >>>> >>>> MCClassDefinition>>printDefinitionOn: >>>> Receiver: a MCClassDefinition(Character) >>>> Arguments and temporary variables: >>>> stream: a WriteStream >>>> Receiver's instance variables: >>>> name: #Character >>>> superclassName: #Magnitude >>>> variables: an OrderedCollection(a >>>> MCClassVariableDefinition(CharacterTable) a M...etc... >>>> category: 'Collections-Strings' >>>> type: #immediate >>>> comment: 'I represent a character by >>>> storing its associated Unicode as an unsig...etc... >>>> commentStamp: 'eem 8/12/2014 14:53' >>>> traitComposition: nil >>>> classTraitComposition: nil >>>> >>>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>>> Receiver: a MCDiffyTextWriter >>>> Arguments and temporary variables: >>>> definition: a WriteStream >>>> s: a MCClassDefinition(Character) >>>> Receiver's instance variables: >>>> stream: a WriteStream >>>> initStream: nil >>>> >>>> >>>> --- The full stack --- >>>> MCClassDefinition(Object)>>error: >>>> MCClassDefinition>>kindOfSubclass >>>> MCClassDefinition>>printDefinitionOn: >>>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>>> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >>>> String class(SequenceableCollection class)>>new:streamContents: >>>> String class(SequenceableCollection class)>>streamContents: >>>> MCDiffyTextWriter(MCTextWriter)>>chunkContents: >>>> MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>>> MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: >>>> MCClassDefinition>>accept: >>>> [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>>> String class(SequenceableCollection class)>>new:streamContents: >>>> String class(SequenceableCollection class)>>streamContents: >>>> MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>>> MCDiffyTextWriter>>writePatchFrom:to: >>>> MCDiffyTextWriter>>writeModification: >>>> [] in MCDiffyTextWriter>>writePatch: >>>> SortedCollection(OrderedCollection)>>do: >>>> MCDiffyTextWriter>>writePatch: >>>> SSDiffyTextWriter>>writePatch: >>>> [] in SSDiffyTextWriter>>writeVersion:for: >>>> BlockClosure>>on:do: >>>> SSDiffyTextWriter>>writeVersion:for: >>>> [] in SSEMailSubscription>>versionAdded:to: >>>> BlockClosure>>on:do: >>>> SSEMailSubscription>>versionAdded:to: >>>> [] in [] in SSProject>>versionAdded: >>>> [] in BlockClosure>>newProcess >>>> >>>> >>>> >>>> >>>> -- >>>> best,Eliot >>>> >>>> >> >> >> > > > -- > best, > Eliot > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/45fdc2e7/attachment.htm From tim.olson.mail at gmail.com Thu May 7 17:47:18 2015 From: tim.olson.mail at gmail.com (Tim Olson) Date: Thu May 7 17:47:53 2015 Subject: [squeak-dev] Re: Problem updating image to latest In-Reply-To: References: Message-ID: Update: I now think the problem is in the Cog VM: I downloaded a clean image from Squeak.org and ran into the same problems (simply opening a Preferences Browser and clicking on the first item in the list will trigger a DNU). Running my current image with an older interpreter VM (Squeak 5.7.4.1) shows no problems. ? tim From karlramberg at gmail.com Thu May 7 18:41:40 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 7 18:41:42 2015 Subject: [squeak-dev] Re: Problem updating image to latest In-Reply-To: References: Message-ID: Yes, it must be the VM I get the same bug Karl On Thu, May 7, 2015 at 7:47 PM, Tim Olson wrote: > Update: > > I now think the problem is in the Cog VM: I downloaded a clean image from > Squeak.org and ran into the same problems (simply opening a Preferences > Browser and clicking on the first item in the list will trigger a DNU). > > Running my current image with an older interpreter VM (Squeak 5.7.4.1) > shows no problems. > > ? tim > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/5cf4a2ce/attachment.htm From johnmci at smalltalkconsulting.com Thu May 7 18:42:41 2015 From: johnmci at smalltalkconsulting.com (John McIntosh) Date: Thu May 7 18:42:46 2015 Subject: [squeak-dev] Pending OS-X Cocoa Squeak VM build Message-ID: Morning. I've taken some time to integrate various Pharo and Pyonkee changes into the Squeak OS-X and iOS cocoa source tree, along with converting the code base to ARC and modern Obj-C. Earlier today I ran a Squeak4.5-13680 32bit image on a 64bit client 3488 run, 3421 passes, 23 expected failures, 43 failures, 0 errors, 1 unexpected passes However I need some folks to step forward and validate the results, document what might be broken, look for behaviour anomalies, and refine exactly what plugins are needed in the base system. I also need someone to try this on a 32bit host with 32bit image, and with a current 64bit image (which I don't have) on a 64bit host. Drop me a note and I"ll forward a link to a binary for testing. Shortly I will be integrating these changes into the Cog branch and create an XCode project for building a 64/64 Cog/etc VM. -- =========================================================================== John M. McIntosh https://www.linkedin.com/in/smalltalk =========================================================================== -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/b28d8e5d/attachment.htm From stephan at stack.nl Thu May 7 18:48:49 2015 From: stephan at stack.nl (stephan) Date: Thu May 7 18:48:04 2015 Subject: [squeak-dev] SelectionMorph send to back Message-ID: <554BB391.4020707@stack.nl> 4.6-14191 (and older, and all Pharo's) When selecting a few windows with shift-drag, sending them to back MNUs SelectionMorph might behave better with an empty implementation of goBehind instead of the current one from Morph SelectionMorph>>goBehind owner addMorphNearBack: self. Stephan From karlramberg at gmail.com Thu May 7 18:50:54 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 7 18:50:57 2015 Subject: Spur Bootstrap (was: Re: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz) In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Ok, I did not know this. I naively tried filing in the trunk changes you posted and ran into this issue. Karl On Thu, May 7, 2015 at 3:56 PM, Levente Uzonyi wrote: > Before Spur Character has always had an instance variable named value. > Characters are immediate in Spur, so the Character class has no instance > variables there. If you browse Collections.spur-ul.584.mcz, you'll find the > following definition: > > Magnitude immediateSubclass: #Character > instanceVariableNames: '' > classVariableNames: 'CharacterTable ClassificationTable > DigitValues LetterBits LowercaseBit UppercaseBit' > poolDictionaries: '' > category: 'Collections-Strings' > > > Levente > > On Thu, 7 May 2015, karl ramberg wrote: > > Then the Character changes must be changedInstance variable value was >> added in Collections.spur-ul.584.mcz it seems like >> >> >> On Thu, May 7, 2015 at 2:03 PM, Tobias Pape wrote: >> >> On 07.05.2015, at 14:01, karl ramberg >> wrote: >> >> > I tried loading these changes manually but my image just crashes >> hard. >> > >> > If I try to add instance variable 'value' to Character I just get >> a debugger and no option to continue. >> > >> > >> >> This may be because Character cannot have instance variables in >> Spur, IIRC? >> >> >> >> > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/7969057b/attachment.htm From karlramberg at gmail.com Thu May 7 19:05:50 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 7 19:05:53 2015 Subject: [squeak-dev] SelectionMorph send to back In-Reply-To: <554BB391.4020707@stack.nl> References: <554BB391.4020707@stack.nl> Message-ID: SelectionMorph does not have a owner. Method should probably be something like SelectionMorph>>goBehind ActiveWorld addMorphNearBack: self. Karl On Thu, May 7, 2015 at 8:48 PM, stephan wrote: > 4.6-14191 (and older, and all Pharo's) > When selecting a few windows with shift-drag, sending them to back MNUs > > SelectionMorph might behave better with an empty implementation > of goBehind instead of the current one from Morph > > SelectionMorph>>goBehind > owner addMorphNearBack: self. > > Stephan > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/a8c5f246/attachment.htm From javier_diaz_r at mac.com Thu May 7 19:55:48 2015 From: javier_diaz_r at mac.com (Javier Diaz-Reinoso) Date: Thu May 7 19:56:04 2015 Subject: [squeak-dev] Pending OS-X Cocoa Squeak VM build In-Reply-To: References: Message-ID: <4A85222C-4CE7-4EB6-BADA-4E98869E3BE9@mac.com> I try to compile but have errors: - In sqSqueakIPhoneApplication+imageReadWrite.m appears to have a } missing (line 125) added and then compile OK. - In SqueakNoOGLIPhoneAppDelegate.m line 68 is: #error JMM notes not tested after integration yet 2015 May 7th line 206 have an autorelease, the errors are: ARC forbids explicit message send of autorelease ? not available in automatic reference counting mode. > On May 7, 2015, at 13:42, John McIntosh wrote: > > Morning. > > I've taken some time to integrate various Pharo and Pyonkee changes into the Squeak OS-X and iOS cocoa source tree, along with converting the code base to ARC and modern Obj-C. > > Earlier today I ran a Squeak4.5-13680 32bit image on a 64bit client > 3488 run, 3421 passes, 23 expected failures, 43 failures, 0 errors, 1 unexpected passes > > However I need some folks to step forward and validate the results, document what might be broken, look for behaviour anomalies, and refine exactly what plugins are needed in the base system. > > I also need someone to try this on a 32bit host with 32bit image, and with a current 64bit image (which I don't have) on a 64bit host. > > Drop me a note and I"ll forward a link to a binary for testing. > > Shortly I will be integrating these changes into the Cog branch and create an XCode project for building a 64/64 Cog/etc VM. > > -- > =========================================================================== > John M. McIntosh > https://www.linkedin.com/in/smalltalk > =========================================================================== > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/65ca8b34/attachment.htm From commits at source.squeak.org Thu May 7 20:01:56 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:01:58 2015 Subject: [squeak-dev] The Trunk: Collections.spur-cmm.603.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-cmm.603.mcz ==================== Summary ==================== Name: Collections.spur-cmm.603 Author: eem Time: 7 May 2015, 11:39:30.962 am UUID: 424c0357-331c-4413-9ddb-153e5548f217 Ancestors: Collections-cmm.603, Collections.spur-mt.602 Collections-cmm.603 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 - Collection>>#groupBy:having: is already being used for non-Integer groups, and integerDictionary is now slower than a regular Dictionary in Spur. - PositionableStream>>#nextInto:, #next:into:, #nextInto:startingAt:, #next:into:startingAt:, and #readInto:startingAt:count require no services specific to PositionableStream. Move them up to Stream and remove the redundant implementations from various subclasses. - Let WeakArray>>#species be a regular Array instead of its own class, so that WeakArray's can be successfully compared to Arrays with equivalent contents. =============== Diff against Collections-cmm.603 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 7 May 2015 8:01:55.898 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 7 20:02:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:02:37 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.625.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.625.mcz ==================== Summary ==================== Name: Collections.spur-ul.625 Author: eem Time: 7 May 2015, 11:46:59.287 am UUID: 682c134b-5dfb-4c57-93be-ca70cf823f4d Ancestors: Collections-ul.625, Collections.spur-ul.624 Collections-ul.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. =============== Diff against Collections-ul.625 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 7 May 2015 8:02:33.769 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 7 20:03:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:03:29 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.629.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.629.mcz ==================== Summary ==================== Name: Collections.spur-mt.629 Author: eem Time: 7 May 2015, 11:43:16.421 am UUID: 9e779f44-55c2-456b-8ef9-3a0f5daaef63 Ancestors: Collections-mt.629, Collections.spur-ul.628 Collections-mt.629 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... =============== Diff against Collections-mt.629 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 7 May 2015 8:03:15.389 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 7 20:03:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:03:56 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.630.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.630.mcz ==================== Summary ==================== Name: Collections.spur-mt.630 Author: eem Time: 7 May 2015, 11:43:23.352 am UUID: 62be78ad-2aee-4651-92e3-4012fadf3c40 Ancestors: Collections-mt.630, Collections.spur-mt.629 Collections-mt.630 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 HTML escaping added to html read/writer =============== Diff against Collections-mt.630 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 7 May 2015 8:03:37.821 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 7 20:04:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:04:14 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.632.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.632.mcz ==================== Summary ==================== Name: Collections.spur-ul.632 Author: eem Time: 7 May 2015, 11:47:08.828 am UUID: 3c592f08-16e3-4b6a-a46a-335035d10022 Ancestors: Collections-ul.632, Collections.spur-mt.631 Collections-ul.632 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Removed MutexForPicking and RandomForPicking from Collection along with the methods referencing them, because the accessor methods were private, and they were only intended to be used for shuffling. Separated #groupBy: from #groupBy:having:. =============== Diff against Collections-ul.632 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 7 May 2015 8:03:56.685 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 7 20:04:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:04:19 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.633.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.633.mcz ==================== Summary ==================== Name: Collections.spur-ul.633 Author: eem Time: 7 May 2015, 11:47:11.951 am UUID: 037f8e06-67c0-4b15-8e9c-9ac414f16d75 Ancestors: Collections-ul.633, Collections.spur-ul.632 Collections-ul.633 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Don't try to use Character's ClassificationTable when the new class variables are not initialized properly. This is a possible workaround to fix the Spur bootstrap. =============== Diff against Collections-ul.633 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 7 May 2015 8:04:12.565 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 7 20:04:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:04:52 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.634.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.634.mcz ==================== Summary ==================== Name: Collections.spur-ul.634 Author: eem Time: 7 May 2015, 11:47:16.223 am UUID: de391e26-1d43-4e05-ae2b-2cb5e09288bf Ancestors: Collections-ul.634, Collections.spur-ul.633 Collections-ul.634 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Revert the workaround from Collections-ul.633. =============== Diff against Collections-ul.634 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 7 May 2015 8:04:49.969 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 7 20:08:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:08:48 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.694.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.694.mcz ==================== Summary ==================== Name: System.spur-cmm.694 Author: eem Time: 7 May 2015, 11:58:12.084 am UUID: df75e321-21b6-4b13-b81a-bfe4ca499f54 Ancestors: System-cmm.694, System.spur-dtl.693 System-cmm.694 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 - #flush stdout and stderr after writing error information to them. - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. =============== Diff against System-cmm.694 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Thu May 7 20:10:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:10:31 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.735.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.735.mcz ==================== Summary ==================== Name: System.spur-kfr.735 Author: eem Time: 7 May 2015, 12:02:00.725 pm UUID: 0b04fba3-fe05-485f-8085-e23c2074a5e4 Ancestors: System-kfr.735, System.spur-topa.734 System-kfr.735 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Changes to use SystemNavigation thoroughSenders: true =============== Diff against System-kfr.735 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Thu May 7 20:11:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:11:03 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.736.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.736.mcz ==================== Summary ==================== Name: System.spur-kfr.736 Author: eem Time: 7 May 2015, 12:02:08.941 pm UUID: 5a78072d-c67b-4bf0-9284-1ca2af60622a Ancestors: System-kfr.736, System.spur-kfr.735 System-kfr.736 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Changes to use pragma preferences where implemented =============== Diff against System-kfr.736 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Thu May 7 20:11:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 20:11:18 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.737.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.737.mcz ==================== Summary ==================== Name: System.spur-ul.737 Author: eem Time: 7 May 2015, 12:05:24.637 pm UUID: 8dcecd31-bb4d-4c18-b4f9-c120e87a95c3 Ancestors: System-ul.737, System.spur-kfr.736 System-ul.737 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 #groupBy:having -> #groupBy: =============== Diff against System-ul.737 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From johnmci at smalltalkconsulting.com Thu May 7 20:18:07 2015 From: johnmci at smalltalkconsulting.com (John McIntosh) Date: Thu May 7 20:18:09 2015 Subject: [squeak-dev] Pending OS-X Cocoa Squeak VM build In-Reply-To: <4A85222C-4CE7-4EB6-BADA-4E98869E3BE9@mac.com> References: <4A85222C-4CE7-4EB6-BADA-4E98869E3BE9@mac.com> Message-ID: Yes, not quite ready for iPhone compiles yet. Which is why the #error still exists. On Thu, May 7, 2015 at 12:55 PM, Javier Diaz-Reinoso wrote: > I try to compile but have errors: > > - In sqSqueakIPhoneApplication+imageReadWrite.m appears to have a } > missing (line 125) added and then compile OK. > > - In SqueakNoOGLIPhoneAppDelegate.m line 68 is: > #error JMM notes not tested after integration yet 2015 May 7th > > line 206 have an autorelease, the errors are: > ARC forbids explicit message send of autorelease ... not available in > automatic reference counting mode. > > On May 7, 2015, at 13:42, John McIntosh > wrote: > > Morning. > > I've taken some time to integrate various Pharo and Pyonkee changes into > the Squeak OS-X and iOS cocoa source tree, along with converting the code > base to ARC and modern Obj-C. > > Earlier today I ran a Squeak4.5-13680 32bit image on a 64bit client > 3488 run, 3421 passes, 23 expected failures, 43 failures, 0 errors, 1 > unexpected passes > > However I need some folks to step forward and validate the results, > document what might be broken, look for behaviour anomalies, and refine > exactly what plugins are needed in the base system. > > I also need someone to try this on a 32bit host with 32bit image, and with > a current 64bit image (which I don't have) on a 64bit host. > > Drop me a note and I"ll forward a link to a binary for testing. > > Shortly I will be integrating these changes into the Cog branch and create > an XCode project for building a 64/64 Cog/etc VM. > > -- > =========================================================================== > John M. McIntosh > https://www.linkedin.com/in/smalltalk > =========================================================================== > > > > > > -- =========================================================================== John M. McIntosh https://www.linkedin.com/in/smalltalk =========================================================================== -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/a45a509b/attachment.htm From eliot.miranda at gmail.com Thu May 7 20:19:57 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 7 20:19:59 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz In-Reply-To: References: <5547b0ca.a560340a.45ad.38cfSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: On Thu, May 7, 2015 at 10:10 AM, Eliot Miranda wrote: > Hi Levente, > > On Thu, May 7, 2015 at 9:34 AM, Eliot Miranda > wrote: > >> Hi Levente, >> >> On Mon, May 4, 2015 at 1:55 PM, Levente Uzonyi wrote: >> >>> I tried to update an old Spur image, and somehow Character >> >>> #isAlphaNumeric from Collections.spur-ul.628 (which should be loaded by >>> update.spur-ul.311) appeared in the image, while loading >>> Collections.spur-tfel.623 from update.spur-mt.310. >>> Assuming that the load order of the packages is untouched, I suspect >>> that the method got merged in from the non-spur branch of Collections >>> somehow. >> >> >> Yes. I see this. The bootstrap is clearly broken. I'll look at this >> right away. >> > > Ah, MCMethodDefinition class>>className: classString > classIsMeta: metaBoolean > selector: selectorString > category: catString > timeStamp: timeString > source: sourceString > ^ self instanceLike: > (self new initializeWithClassName: classString > classIsMeta: metaBoolean > selector: selectorString > category: catString > timeStamp: timeString > source: sourceString) > > this will share definitions, and given that I'm modifying definitions as > part of the patch process I guess I could end up modifying a definition > that was inadvertently shared. I'm rewriting to avoid use of shared > instances. i.e. I will use MCMethodDefinition new initializeWithClassName > ... instead of MCMethodDefinition className: ... > Ah, the issue is only that the bootstrap is confused by two packages with the same version number, i.e. Collections.spur-ul.624 and Collections.spur-tfel.624. Stupidly I didn't check before uploading new versions of the Spur packages. Forgive the noise. But at least I know what to fix now. > > >> >>> >>> >>> Levente >>> >>> >>> On Mon, 4 May 2015, Levente Uzonyi wrote: >>> >>> On Mon, 4 May 2015, Eliot Miranda wrote: >>>> >>>> This breaks my image, dumping it into the emergency evaluator, I >>>>> *think* because the new LetterMask, AlphaNumbericMask and DigitBit >>>>> variables are not handledf correctly by the Spur bootstrap. Sigh. So for >>>>> those of you using Spur please *don't* update until I've fixed the >>>>> bootstrap. >>>>> You know, by /not/ releasing, we are delaying because now I am fixing >>>>> the bootstrap to keep up with development, instead of us having released, >>>>> and being able to freely commit on Spur. We are now wasting >>>>> cycles. At least I am. >>>>> >>>> >>>> Multilingual-ul.209 should be loaded before Collections-ul.627, and >>>> only then should Collections-ul.628 be loaded. >>>> >>>> In the regular Trunk, I added an update map which loads >>>> Multilingual-ul.209 and Collections-ul.627 first. (Multilingual was before >>>> Collections in the map, so the load order was already guaranteed). >>>> >>>> Levente >>>> >>>> >>>>> On Mon, May 4, 2015 at 10:46 AM, wrote: >>>>> Eliot Miranda uploaded a new version of Collections to project >>>>> The Trunk: >>>>> http://source.squeak.org/trunk/Collections.spur-nice.622.mcz >>>>> >>>>> ==================== Summary ==================== >>>>> >>>>> Name: Collections.spur-nice.622 >>>>> Author: eem >>>>> Time: 4 May 2015, 10:45:05.244 am >>>>> UUID: 02450614-82e9-4d33-95fd-3fede06790d2 >>>>> Ancestors: Collections-nice.622, Collections.spur-mt.621 >>>>> >>>>> Collections-nice.622 patched for Spur by >>>>> SpurBootstrapMonticelloPackagePatcher Cog-eem.262 >>>>> >>>>> #toBraceStack: is not used for compiling { } for so long that >>>>> it's really time to get rid of it. >>>>> >>>>> Symbol>>numArgs: does not need to copy self into a temp var. >>>>> >>>>> =============== Diff against Collections-nice.622 =============== >>>>> >>>>> Item was changed: >>>>> ----- Method: Array>>elementsExchangeIdentityWith: (in >>>>> category 'converting') ----- >>>>> elementsExchangeIdentityWith: otherArray >>>>> + "This primitive performs a bulk mutation, causing all >>>>> pointers to the elements of the >>>>> + receiver to be replaced by pointers to the >>>>> corresponding elements of otherArray. >>>>> + At the same time, all pointers to the elements of >>>>> otherArray are replaced by >>>>> + pointers to the corresponding elements of this array. >>>>> The identityHashes remain >>>>> + with the pointers rather than with the objects so that >>>>> objects in hashed structures >>>>> + should still be properly indexed after the mutation." >>>>> - "This primitive performs a bulk mutation, causing all >>>>> pointers to the elements of this array to be replaced by pointers to the >>>>> corresponding elements of otherArray. At the same time, all >>>>> pointers to the elements of otherArray are replaced by pointers >>>>> to the corresponding elements of this array. The identityHashes remain >>>>> with the pointers rather than with the objects so that >>>>> objects in hashed structures should still be properly indexed >>>>> after the mutation." >>>>> >>>>> + >>>>> + ec == #'bad receiver' ifTrue: >>>>> + [^self error: 'receiver must be of class Array']. >>>>> + ec == #'bad argument' ifTrue: >>>>> + [^self error: (otherArray class == Array >>>>> + ifTrue: ['arg >>>>> must be of class Array'] >>>>> + ifFalse: >>>>> ['receiver and argument must have the same size'])]. >>>>> + ec == #'inappropriate operation' ifTrue: >>>>> + [^self error: 'can''t become immediates such as >>>>> SmallIntegers or Characters']. >>>>> + ec == #'no modification' ifTrue: >>>>> + [^self error: 'can''t become immutable objects']. >>>>> + ec == #'object is pinned' ifTrue: >>>>> + [^self error: 'can''t become pinned objects']. >>>>> + ec == #'insufficient object memory' ifTrue: >>>>> + [Smalltalk garbageCollect < 1048576 ifTrue: >>>>> + [Smalltalk growMemoryByAtLeast: 1048576]. >>>>> + ^self elementsExchangeIdentityWith: otherArray]. >>>>> + self primitiveFailed! >>>>> - >>>>> - otherArray class == Array ifFalse: [^ self error: 'arg >>>>> must be array']. >>>>> - self size = otherArray size ifFalse: [^ self error: >>>>> 'arrays must be same size']. >>>>> - (self anySatisfy: [:obj | obj class == SmallInteger]) >>>>> ifTrue: [^ self error: 'can''t become SmallIntegers']. >>>>> - (otherArray anySatisfy: [:obj | obj class == >>>>> SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. >>>>> - self with: otherArray do:[:a :b| a == b ifTrue:[^self >>>>> error:'can''t become yourself']]. >>>>> - >>>>> - "Must have failed because not enough space in forwarding >>>>> table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). >>>>> Do GC and try again only once" >>>>> - (Smalltalk bytesLeft: true) = Smalltalk >>>>> primitiveGarbageCollect >>>>> - ifTrue: [^ self primitiveFailed]. >>>>> - ^ self elementsExchangeIdentityWith: otherArray! >>>>> >>>>> Item was changed: >>>>> ----- Method: Array>>elementsForwardIdentityTo: (in category >>>>> 'converting') ----- >>>>> elementsForwardIdentityTo: otherArray >>>>> + "This primitive performs a bulk mutation, causing all >>>>> pointers to the elements of the >>>>> + receiver to be replaced by pointers to the >>>>> corresponding elements of otherArray. >>>>> + The identityHashes remain with the pointers rather than >>>>> with the objects so that >>>>> + the objects in this array should still be properly >>>>> indexed in any existing hashed >>>>> + structures after the mutation." >>>>> + >>>>> - "This primitive performs a bulk mutation, causing all >>>>> pointers to the elements of this array to be replaced by pointers to the >>>>> corresponding elements of otherArray. The identityHashes >>>>> remain with the pointers rather than with the objects so that >>>>> the objects in this array should still be properly indexed in any existing >>>>> hashed structures after the mutation." >>>>> - >>>>> self primitiveFailed! >>>>> >>>>> Item was changed: >>>>> ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in >>>>> category 'converting') ----- >>>>> elementsForwardIdentityTo: otherArray copyHash: copyHash >>>>> + "This primitive performs a bulk mutation, causing all >>>>> pointers to the elements of the >>>>> + receiver to be replaced by pointers to the >>>>> corresponding elements of otherArray. >>>>> + If copyHash is true, the identityHashes remain with the >>>>> pointers rather than with the >>>>> + objects so that the objects in the receiver should >>>>> still be properly indexed in any >>>>> + existing hashed structures after the mutation. If >>>>> copyHash is false, then the hashes >>>>> + of the objects in otherArray remain unchanged. If you >>>>> know what you're doing this >>>>> + may indeed be what you want." >>>>> + >>>>> - "This primitive performs a bulk mutation, causing all >>>>> pointers to the elements of this array to be replaced by pointers to the >>>>> corresponding elements of otherArray. The identityHashes >>>>> remain with the pointers rather than with the objects so that >>>>> the objects in this array should still be properly indexed in any existing >>>>> hashed structures after the mutation." >>>>> - >>>>> self primitiveFailed! >>>>> >>>>> Item was changed: >>>>> ==== ERROR === >>>>> >>>>> Error: Unrecognized class type >>>>> >>>>> 4 May 2015 5:47:40.493 pm >>>>> >>>>> VM: unix - a SmalltalkImage >>>>> Image: Squeak3.11alpha [latest update: #8824] >>>>> >>>>> SecurityManager state: >>>>> Restricted: false >>>>> FileAccess: true >>>>> SocketAccess: true >>>>> Working Dir /home/squeaksource >>>>> Trusted Dir /home/squeaksource/secure >>>>> Untrusted Dir /home/squeaksource/My Squeak >>>>> >>>>> MCClassDefinition(Object)>>error: >>>>> Receiver: a MCClassDefinition(Character) >>>>> Arguments and temporary variables: >>>>> aString: 'Unrecognized class type' >>>>> Receiver's instance variables: >>>>> name: #Character >>>>> superclassName: #Magnitude >>>>> variables: an OrderedCollection(a >>>>> MCClassVariableDefinition(CharacterTable) a M...etc... >>>>> category: 'Collections-Strings' >>>>> type: #immediate >>>>> comment: 'I represent a character by >>>>> storing its associated Unicode as an unsig...etc... >>>>> commentStamp: 'eem 8/12/2014 14:53' >>>>> traitComposition: nil >>>>> classTraitComposition: nil >>>>> >>>>> MCClassDefinition>>kindOfSubclass >>>>> Receiver: a MCClassDefinition(Character) >>>>> Arguments and temporary variables: >>>>> >>>>> Receiver's instance variables: >>>>> name: #Character >>>>> superclassName: #Magnitude >>>>> variables: an OrderedCollection(a >>>>> MCClassVariableDefinition(CharacterTable) a M...etc... >>>>> category: 'Collections-Strings' >>>>> type: #immediate >>>>> comment: 'I represent a character by >>>>> storing its associated Unicode as an unsig...etc... >>>>> commentStamp: 'eem 8/12/2014 14:53' >>>>> traitComposition: nil >>>>> classTraitComposition: nil >>>>> >>>>> MCClassDefinition>>printDefinitionOn: >>>>> Receiver: a MCClassDefinition(Character) >>>>> Arguments and temporary variables: >>>>> stream: a WriteStream >>>>> Receiver's instance variables: >>>>> name: #Character >>>>> superclassName: #Magnitude >>>>> variables: an OrderedCollection(a >>>>> MCClassVariableDefinition(CharacterTable) a M...etc... >>>>> category: 'Collections-Strings' >>>>> type: #immediate >>>>> comment: 'I represent a character by >>>>> storing its associated Unicode as an unsig...etc... >>>>> commentStamp: 'eem 8/12/2014 14:53' >>>>> traitComposition: nil >>>>> classTraitComposition: nil >>>>> >>>>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>>>> Receiver: a MCDiffyTextWriter >>>>> Arguments and temporary variables: >>>>> definition: a WriteStream >>>>> s: a MCClassDefinition(Character) >>>>> Receiver's instance variables: >>>>> stream: a WriteStream >>>>> initStream: nil >>>>> >>>>> >>>>> --- The full stack --- >>>>> MCClassDefinition(Object)>>error: >>>>> MCClassDefinition>>kindOfSubclass >>>>> MCClassDefinition>>printDefinitionOn: >>>>> [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>>>> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >>>>> - >>>>> String class(SequenceableCollection class)>>new:streamContents: >>>>> String class(SequenceableCollection class)>>streamContents: >>>>> MCDiffyTextWriter(MCTextWriter)>>chunkContents: >>>>> MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: >>>>> MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: >>>>> MCClassDefinition>>accept: >>>>> [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>>>> String class(SequenceableCollection class)>>new:streamContents: >>>>> String class(SequenceableCollection class)>>streamContents: >>>>> MCDiffyTextWriter(MCTextWriter)>>visitInFork: >>>>> MCDiffyTextWriter>>writePatchFrom:to: >>>>> MCDiffyTextWriter>>writeModification: >>>>> [] in MCDiffyTextWriter>>writePatch: >>>>> SortedCollection(OrderedCollection)>>do: >>>>> MCDiffyTextWriter>>writePatch: >>>>> SSDiffyTextWriter>>writePatch: >>>>> [] in SSDiffyTextWriter>>writeVersion:for: >>>>> BlockClosure>>on:do: >>>>> SSDiffyTextWriter>>writeVersion:for: >>>>> [] in SSEMailSubscription>>versionAdded:to: >>>>> BlockClosure>>on:do: >>>>> SSEMailSubscription>>versionAdded:to: >>>>> [] in [] in SSProject>>versionAdded: >>>>> [] in BlockClosure>>newProcess >>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> best,Eliot >>>>> >>>>> >>> >>> >>> >> >> >> -- >> best, >> Eliot >> > > > > -- > best, > Eliot > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/23ef0677/attachment-0001.htm From commits at source.squeak.org Thu May 7 21:55:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 7 21:55:06 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150507215505.31666.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008313.html Name: ShoutTests-ul.26 Ancestors: ShoutTests-topa.25 Pass a String to SHParserST80, not a Text. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008314.html Name: Help-Squeak-TerseGuide-kfr.5 Ancestors: Help-Squeak-TerseGuide-dhn.4 Expanded Rectangle guide a little ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008315.html Name: Collections-ul.634 Ancestors: Collections-ul.633 Revert the workaround from Collections-ul.633. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008316.html Name: Collections.spur-cmm.603 Ancestors: Collections-cmm.603, Collections.spur-mt.602 Collections-cmm.603 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 - Collection>>#groupBy:having: is already being used for non-Integer groups, and integerDictionary is now slower than a regular Dictionary in Spur. - PositionableStream>>#nextInto:, #next:into:, #nextInto:startingAt:, #next:into:startingAt:, and #readInto:startingAt:count require no services specific to PositionableStream. Move them up to Stream and remove the redundant implementations from various subclasses. - Let WeakArray>>#species be a regular Array instead of its own class, so that WeakArray's can be successfully compared to Arrays with equivalent contents. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008317.html Name: Collections.spur-ul.625 Ancestors: Collections-ul.625, Collections.spur-ul.624 Collections-ul.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008318.html Name: Collections.spur-mt.629 Ancestors: Collections-mt.629, Collections.spur-ul.628 Collections-mt.629 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008319.html Name: Collections.spur-mt.630 Ancestors: Collections-mt.630, Collections.spur-mt.629 Collections-mt.630 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 HTML escaping added to html read/writer ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008320.html Name: Collections.spur-ul.632 Ancestors: Collections-ul.632, Collections.spur-mt.631 Collections-ul.632 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Removed MutexForPicking and RandomForPicking from Collection along with the methods referencing them, because the accessor methods were private, and they were only intended to be used for shuffling. Separated #groupBy: from #groupBy:having:. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008321.html Name: Collections.spur-ul.633 Ancestors: Collections-ul.633, Collections.spur-ul.632 Collections-ul.633 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Don't try to use Character's ClassificationTable when the new class variables are not initialized properly. This is a possible workaround to fix the Spur bootstrap. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008322.html Name: Collections.spur-ul.634 Ancestors: Collections-ul.634, Collections.spur-ul.633 Collections-ul.634 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Revert the workaround from Collections-ul.633. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008323.html Name: System.spur-cmm.694 Ancestors: System-cmm.694, System.spur-dtl.693 System-cmm.694 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 - #flush stdout and stderr after writing error information to them. - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008324.html Name: System.spur-kfr.735 Ancestors: System-kfr.735, System.spur-topa.734 System-kfr.735 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Changes to use SystemNavigation thoroughSenders: true ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008325.html Name: System.spur-kfr.736 Ancestors: System-kfr.736, System.spur-kfr.735 System-kfr.736 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 Changes to use pragma preferences where implemented ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008326.html Name: System.spur-ul.737 Ancestors: System-ul.737, System.spur-kfr.736 System-ul.737 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.264 #groupBy:having -> #groupBy: ============================================= From eliot.miranda at gmail.com Thu May 7 23:58:55 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 7 23:58:58 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? Message-ID: Hi All, I need to delete all the patched Spur packages in trunk to ensure that correctly patched versions replace them. Is there an automated way of deleting packages on trunk? I've used the web interface, but it'll take all day :-( -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150507/f762566b/attachment.htm From lewis at mail.msen.com Fri May 8 01:09:10 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri May 8 01:09:13 2015 Subject: [squeak-dev] Re: [Vm-dev] Pending OS-X Cocoa Squeak VM build In-Reply-To: References: Message-ID: <20150508010910.GA93928@shell.msen.com> On Thu, May 07, 2015 at 11:42:41AM -0700, John McIntosh wrote: > > Morning. > > I've taken some time to integrate various Pharo and Pyonkee changes into > the Squeak OS-X and iOS cocoa source tree, along with converting the code > base to ARC and modern Obj-C. > > Earlier today I ran a Squeak4.5-13680 32bit image on a 64bit client > 3488 run, 3421 passes, 23 expected failures, 43 failures, 0 errors, 1 > unexpected passes > > However I need some folks to step forward and validate the results, > document what might be broken, look for behaviour anomalies, and refine > exactly what plugins are needed in the base system. > > I also need someone to try this on a 32bit host with 32bit image, and with > a current 64bit image (which I don't have) on a 64bit host. Hi John, You can download a current 64-bit image from http://build.squeak.org/job/Squeak%2064-bit%20image/ This is an updated trunk image traced freshly on a daily basis. It is a traditional 68002 64-bit image (not the Spur 68019 64-bit image format). Dave > > Drop me a note and I"ll forward a link to a binary for testing. > > Shortly I will be integrating these changes into the Cog branch and create > an XCode project for building a 64/64 Cog/etc VM. > > -- > =========================================================================== > John M. McIntosh > https://www.linkedin.com/in/smalltalk > =========================================================================== From lewis at mail.msen.com Fri May 8 02:19:49 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri May 8 02:19:51 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: Message-ID: <20150508021949.GA7296@shell.msen.com> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: > Hi All, > > I need to delete all the patched Spur packages in trunk to ensure that > correctly patched versions replace them. Is there an automated way of > deleting packages on trunk? I've used the web interface, but it'll take > all day :-( > -- > best, > Eliot I don't know the answer to your question, but if I look at the files in the squeaksource repository, there are quite a few: davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz | wc -l 246 davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd | wc -l 152 davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm | wc -l 33 davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | wc -l 450 Is it really necessary to delete all of this stuff? Or could we keep it as is, and work around the problems in some other way? Dave From Das.Linux at gmx.de Fri May 8 06:40:15 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri May 8 06:40:19 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: <20150508021949.GA7296@shell.msen.com> References: <20150508021949.GA7296@shell.msen.com> Message-ID: <58CBE4F7-1FED-4282-B7F0-E333CE567EB1@gmx.de> On 08.05.2015, at 04:19, David T. Lewis wrote: > On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >> Hi All, >> >> I need to delete all the patched Spur packages in trunk to ensure that >> correctly patched versions replace them. Is there an automated way of >> deleting packages on trunk? I've used the web interface, but it'll take >> all day :-( There are ways to do that; with access to the sso-image, it would take me roughly an hour to two do that cleanly. Best regards -Tobias >> -- >> best, >> Eliot > > I don't know the answer to your question, but if I look at the files in > the squeaksource repository, there are quite a few: > > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz | wc -l > 246 > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd | wc -l > 152 These don't count :) > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm | wc -l > 33 > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | wc -l > 450 > > Is it really necessary to delete all of this stuff? Or could we keep it as is, and > work around the problems in some other way? From commits at source.squeak.org Fri May 8 09:01:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 09:01:28 2015 Subject: [squeak-dev] The Trunk: Tools-mt.622.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.622.mcz ==================== Summary ==================== Name: Tools-mt.622 Author: mt Time: 8 May 2015, 11:01:04.067 am UUID: d6bbe089-6caa-bb48-8823-ac746a9fc3f1 Ancestors: Tools-mt.621 Fixed regression in Message Names tool. Support multi-line search pattern input again. =============== Diff against Tools-mt.621 =============== Item was changed: ----- Method: MessageNames>>buildSearchPaneWith: (in category 'toolbuilder') ----- buildSearchPaneWith: builder | panelSpec textSpec buttonSpec | panelSpec := builder pluggablePanelSpec new layout: #horizontal; children: OrderedCollection new; yourself. + textSpec := builder pluggableTextSpec new. - textSpec := builder pluggableInputFieldSpec new. textSpec model: searchString; help: 'Type here, then hit Search.' translated; getText: #contents; setText: #contents:. panelSpec children add: textSpec. buttonSpec := builder pluggableActionButtonSpec new. buttonSpec model: self; label: 'Search'; action: #doSearch; horizontalResizing: #shrinkWrap. panelSpec children add: buttonSpec. ^ panelSpec! Item was changed: ----- Method: MessageNames>>buildWith: (in category 'toolbuilder') ----- buildWith: builder "ToolBuilder open: MessageNames new" | windowSpec max searchHeight | max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5]. searchHeight := Preferences standardDefaultTextFont height * 2. windowSpec := self buildWindowWith: builder specs: { + (0@0 corner: 0.5@0.1) -> [self buildSearchPaneWith: builder]. + (0@0.1 corner: 0.5 @ max) -> [self buildSelectorListWith: builder]. - (self topConstantHeightFrame: searchHeight fromLeft: 0 width: 0.5) -> [self buildSearchPaneWith: builder]. - (self frameOffsetFromTop: searchHeight fromLeft: 0 width: 0.5 bottomFraction: max) -> [self buildSelectorListWith: builder]. (0.5@0.0 corner: 1.0@max) -> [self buildMessageListWith: builder]. (0@max corner: 1@1) -> [self buildCodePaneWith: builder]. }. ^ builder build: windowSpec! From commits at source.squeak.org Fri May 8 09:06:23 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 09:06:25 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.970.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.970.mcz ==================== Summary ==================== Name: Morphic-mt.970 Author: mt Time: 8 May 2015, 11:05:37.172 am UUID: 038037d4-21ee-d04e-8767-5d888876a367 Ancestors: Morphic-mt.969 Use a reduced minimum width fors buttons if they are #shrinkWrap. Better for lower resolutions resp. tool window sizes. =============== Diff against Morphic-mt.969 =============== Item was changed: ----- Method: PluggableButtonMorph>>updateMinimumExtent (in category 'layout') ----- updateMinimumExtent | hMin vMin | self label isMorph ifTrue: [^ self minimumExtent: self label minExtent]. hMin := vMin := 0. self hResizing == #shrinkWrap + ifTrue: [hMin := (self font widthOfString: self label)]. - ifTrue: [hMin := (self font widthOfString: self label) max: self labelShrinkThreshold]. self vResizing == #shrinkWrap ifTrue: [vMin := self font height]. hMin := hMin + (2* self borderStyle width). vMin := vMin + (2* self borderStyle width). self layoutInset isRectangle ifTrue: [ hMin := hMin + self layoutInset left + self layoutInset right. vMin := vMin + self layoutInset top + self layoutInset bottom] ifFalse: [self layoutInset isPoint ifTrue: [ hMin := hMin + (2* self layoutInset x). vMin := vMin + (2* self layoutInset y)] ifFalse: [ hMin := hMin + (2* self layoutInset). vMin := vMin + (2* self layoutInset)]]. self minimumExtent: hMin @ vMin. "Since we have no submorphs, we have to resize here if we want to shrink wrap." self hResizing == #shrinkWrap ifTrue: [self width: hMin]. self vResizing == #shrinkWrap ifTrue: [self height: vMin].! From commits at source.squeak.org Fri May 8 09:11:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 09:11:28 2015 Subject: [squeak-dev] The Trunk: Tools-mt.623.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.623.mcz ==================== Summary ==================== Name: Tools-mt.623 Author: mt Time: 8 May 2015, 11:11:07.916 am UUID: 4f937cd2-ceaa-de4a-b47c-c4762865eb22 Ancestors: Tools-mt.622 Re-order instance/?/class switches in browsers to instance/class/? as discussed here: http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991.html Assumption: Switching between instance/class is used more often than ? . Also, instance/class are more cohesive but ? is something special. =============== Diff against Tools-mt.622 =============== Item was changed: ----- Method: Browser>>buildSwitchesWith: (in category 'toolbuilder') ----- buildSwitchesWith: builder "Build the instance/comment/class switch" + | panelSpec i q c | - | panelSpec buttonSpec | panelSpec := builder pluggablePanelSpec new layout: #horizontal; + spacing: -1; children: OrderedCollection new; yourself. + i := builder pluggableButtonSpec new. + i - buttonSpec := builder pluggableButtonSpec new. - buttonSpec model: self; label: 'instance'; help: 'Show instance-side methods' translated; state: #instanceMessagesIndicated; action: #indicateInstanceMessages. - panelSpec children addLast: buttonSpec. + q := builder pluggableButtonSpec new. + q - buttonSpec := builder pluggableButtonSpec new. - buttonSpec model: self; + horizontalResizing: #shrinkWrap; label: '?'; help: 'Cycle between definition, comment, and hierarchy view' translated; state: #classCommentIndicated; action: #plusButtonHit. - panelSpec children addLast: buttonSpec. + c := builder pluggableButtonSpec new. + c - buttonSpec := builder pluggableButtonSpec new. - buttonSpec model: self; label: 'class'; help: 'Show class-side methods' translated; state: #classMessagesIndicated; action: #indicateClassMessages. + + panelSpec children addAll: { + i. c. + builder pluggableSpacerSpec new. + q + }. - panelSpec children addLast: buttonSpec. ^panelSpec! From karlramberg at gmail.com Fri May 8 09:27:10 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri May 8 09:27:13 2015 Subject: [squeak-dev] The Trunk: Tools-mt.622.mcz In-Reply-To: <554c7b6f.04a1340a.2c43.ffff81cdSMTPIN_ADDED_MISSING@mx.google.com> References: <554c7b6f.04a1340a.2c43.ffff81cdSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Can you add the menu also to ease copy pasting with mouse in text field ? Karl On Fri, May 8, 2015 at 11:01 AM, wrote: > Marcel Taeumel uploaded a new version of Tools to project The Trunk: > http://source.squeak.org/trunk/Tools-mt.622.mcz > > ==================== Summary ==================== > > Name: Tools-mt.622 > Author: mt > Time: 8 May 2015, 11:01:04.067 am > UUID: d6bbe089-6caa-bb48-8823-ac746a9fc3f1 > Ancestors: Tools-mt.621 > > Fixed regression in Message Names tool. Support multi-line search pattern > input again. > > =============== Diff against Tools-mt.621 =============== > > Item was changed: > ----- Method: MessageNames>>buildSearchPaneWith: (in category > 'toolbuilder') ----- > buildSearchPaneWith: builder > > | panelSpec textSpec buttonSpec | > panelSpec := builder pluggablePanelSpec new > layout: #horizontal; > children: OrderedCollection new; > yourself. > > + textSpec := builder pluggableTextSpec new. > - textSpec := builder pluggableInputFieldSpec new. > textSpec > model: searchString; > help: 'Type here, then hit Search.' translated; > getText: #contents; > setText: #contents:. > panelSpec children add: textSpec. > > buttonSpec := builder pluggableActionButtonSpec new. > buttonSpec > model: self; > label: 'Search'; > action: #doSearch; > horizontalResizing: #shrinkWrap. > panelSpec children add: buttonSpec. > > ^ panelSpec! > > Item was changed: > ----- Method: MessageNames>>buildWith: (in category 'toolbuilder') ----- > buildWith: builder > "ToolBuilder open: MessageNames new" > > | windowSpec max searchHeight | > max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5]. > searchHeight := Preferences standardDefaultTextFont height * 2. > > windowSpec := self buildWindowWith: builder specs: { > + (0@0 corner: 0.5@0.1) -> [self buildSearchPaneWith: > builder]. > + (0@0.1 corner: 0.5 @ max) -> [self buildSelectorListWith: > builder]. > - (self topConstantHeightFrame: searchHeight fromLeft: 0 > width: 0.5) -> [self buildSearchPaneWith: builder]. > - (self frameOffsetFromTop: searchHeight fromLeft: 0 width: > 0.5 bottomFraction: max) -> [self buildSelectorListWith: builder]. > (0.5@0.0 corner: 1.0@max) -> [self buildMessageListWith: > builder]. > (0@max corner: 1@1) -> [self buildCodePaneWith: builder]. > }. > > ^ builder build: windowSpec! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/52956082/attachment.htm From commits at source.squeak.org Fri May 8 09:28:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 09:28:05 2015 Subject: [squeak-dev] The Trunk: Tools-mt.624.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.624.mcz ==================== Summary ==================== Name: Tools-mt.624 Author: mt Time: 8 May 2015, 11:27:45.242 am UUID: a2e38d15-f1d7-bb41-9f2e-d2f9f5eb5f47 Ancestors: Tools-mt.623 Some other regressions fixed in Message Names tool regarding selections. =============== Diff against Tools-mt.623 =============== Item was changed: ----- Method: MessageNames>>initialize (in category 'initialization') ----- initialize super initialize. searchString := ValueHolder new contents: ''. searchString addDependent: self. selectorList := #(). + selectorListIndex := 0. + + self messageListIndex: 0.! - selectorListIndex := 0.! Item was changed: ----- Method: MessageNames>>selectorListIndex: (in category 'selector list') ----- selectorListIndex: anInteger "Set the selectorListIndex as specified, and propagate consequences" selectorListIndex := anInteger. self changed: #selectorListIndex. messageList := self computeMessageList. + self changed: #messageList. + + "Select the first message if any." + self messageListIndex: (1 min: messageList size).! - self changed: #messageList.! From commits at source.squeak.org Fri May 8 10:35:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 10:35:09 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.971.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.971.mcz ==================== Summary ==================== Name: Morphic-mt.971 Author: mt Time: 8 May 2015, 12:34:26.045 pm UUID: 6bbf9618-bfc6-2b44-aac0-c542bb09ce4d Ancestors: Morphic-mt.970 More workspace capabilities added to search bar. Old search bar morph deprecated. =============== Diff against Morphic-mt.970 =============== Item was changed: Model subclass: #SearchBar + instanceVariableNames: 'searchTerm selection resultsWidget workspace' - instanceVariableNames: 'searchTerm selection resultsWidget' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Menus-DockingBar'! Item was added: + ----- Method: SearchBar>>bindingOf: (in category 'accessing') ----- + bindingOf: x + + ^ self workspace bindingOf: x! Item was added: + ----- Method: SearchBar>>workspace (in category 'accessing') ----- + workspace + + ^ workspace ifNil: [workspace := Workspace new]! Item was removed: - TextMorph subclass: #SearchBarMorph - instanceVariableNames: '' - classVariableNames: '' - poolDictionaries: '' - category: 'Morphic-Menus-DockingBar'! Item was removed: - ----- Method: SearchBarMorph>>activate: (in category 'search') ----- - activate: event - - event hand newKeyboardFocus: self. - self selectAll! Item was removed: - ----- Method: SearchBarMorph>>fillStyle (in category 'initialize') ----- - fillStyle - - ^backgroundColor! Item was removed: - ----- Method: SearchBarMorph>>initialize (in category 'initialize') ----- - initialize - - super initialize. - text := Text new. - backgroundColor := TranslucentColor gray alpha: 0.3. - self width: 200. - self crAction: (MessageSend receiver: self selector: #smartSearch:). - self setBalloonText: 'Searches for globals and methods'.! Item was removed: - ----- Method: SearchBarMorph>>smartSearch: (in category 'search') ----- - smartSearch: evt - "Take the user input and perform an appropriate search" - | input newContents | - input := self contents asString ifEmpty:[^self]. - (Smalltalk bindingOf: input) ifNotNil:[:assoc| | global | - "It's a global or a class" - global := assoc value. - ^ToolSet browse: (global isBehavior ifTrue:[global] ifFalse:[global class]) selector: nil. - ]. - (SystemNavigation new allImplementorsOf: input asSymbol) ifNotEmpty:[:list| - ^SystemNavigation new - browseMessageList: list - name: 'Implementors of ' , input - ]. - input first isUppercase ifTrue:[ - (UIManager default classFromPattern: input withCaption: '') ifNotNil:[:aClass| - ^ToolSet browse: aClass selector: nil. - ]. - ] ifFalse:[ - ^ToolSet default browseMessageNames: input - ]. - newContents := input, ' -- not found.'. - self - newContents: newContents; - selectFrom: input size+1 to: newContents size. - evt hand newKeyboardFocus: self! From commits at source.squeak.org Fri May 8 10:35:49 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 10:35:51 2015 Subject: [squeak-dev] The Trunk: 46Deprecated-mt.3.mcz Message-ID: Marcel Taeumel uploaded a new version of 46Deprecated to project The Trunk: http://source.squeak.org/trunk/46Deprecated-mt.3.mcz ==================== Summary ==================== Name: 46Deprecated-mt.3 Author: mt Time: 8 May 2015, 12:35:45.873 pm UUID: 8ff69d8d-675d-2342-a98a-342fb0a5ddbd Ancestors: 46Deprecated-mt.2 Old search bar morph added to keep that code in case of regression bugs with the new, toolbuilder-driven search bar. =============== Diff against 46Deprecated-mt.2 =============== Item was changed: + SystemOrganization addCategory: #'46Deprecated-Morphic'! - SystemOrganization addCategory: #'46Deprecated-Morphic-Pluggable Widgets'! Item was changed: PluggableListMorph subclass: #PluggableMessageCategoryListMorph instanceVariableNames: 'getRawListSelector priorRawList' classVariableNames: '' poolDictionaries: '' + category: '46Deprecated-Morphic'! - category: '46Deprecated-Morphic-Pluggable Widgets'! !PluggableMessageCategoryListMorph commentStamp: '' prior: 0! A variant of PluggableListMorph designed specially for efficient handling of the --all-- feature in message-list panes. In order to be able *quickly* to check whether there has been an external change to the list, we cache the raw list for identity comparison (the actual list is a combination of the --all-- element and the the actual list).! Item was added: + TextMorph subclass: #SearchBarMorph + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: '46Deprecated-Morphic'! Item was added: + ----- Method: SearchBarMorph>>activate: (in category 'search') ----- + activate: event + + event hand newKeyboardFocus: self. + self selectAll! Item was added: + ----- Method: SearchBarMorph>>fillStyle (in category 'initialize') ----- + fillStyle + + ^backgroundColor! Item was added: + ----- Method: SearchBarMorph>>initialize (in category 'initialize') ----- + initialize + + super initialize. + text := Text new. + backgroundColor := TranslucentColor gray alpha: 0.3. + self width: 200. + self crAction: (MessageSend receiver: self selector: #smartSearch:). + self setBalloonText: 'Searches for globals and methods'.! Item was added: + ----- Method: SearchBarMorph>>smartSearch: (in category 'search') ----- + smartSearch: evt + "Take the user input and perform an appropriate search" + | input newContents | + input := self contents asString ifEmpty:[^self]. + (Smalltalk bindingOf: input) ifNotNil:[:assoc| | global | + "It's a global or a class" + global := assoc value. + ^ToolSet browse: (global isBehavior ifTrue:[global] ifFalse:[global class]) selector: nil. + ]. + (SystemNavigation new allImplementorsOf: input asSymbol) ifNotEmpty:[:list| + ^SystemNavigation new + browseMessageList: list + name: 'Implementors of ' , input + ]. + input first isUppercase ifTrue:[ + (UIManager default classFromPattern: input withCaption: '') ifNotNil:[:aClass| + ^ToolSet browse: aClass selector: nil. + ]. + ] ifFalse:[ + ^ToolSet default browseMessageNames: input + ]. + newContents := input, ' -- not found.'. + self + newContents: newContents; + selectFrom: input size+1 to: newContents size. + evt hand newKeyboardFocus: self! From Marcel.Taeumel at hpi.de Fri May 8 11:05:28 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Fri May 8 11:21:28 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: References: Message-ID: <1431083128070-4825254.post@n4.nabble.com> Not easily... Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4825254.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From stephan at stack.nl Fri May 8 11:28:59 2015 From: stephan at stack.nl (Stephan Eggermont) Date: Fri May 8 11:29:18 2015 Subject: [squeak-dev] Re: SelectionMorph send to back In-Reply-To: References: <554BB391.4020707@stack.nl> Message-ID: On 07/05/15 21:05, karl ramberg wrote: > SelectionMorph does not have a owner. > Method should probably be something like > > SelectionMorph>>goBehind > ActiveWorld addMorphNearBack: self. Does it actually need to do anything? It responds true to wantsToBeTopmost. Stephan From nicolaihess at web.de Fri May 8 11:55:06 2015 From: nicolaihess at web.de (Nicolai Hess) Date: Fri May 8 11:55:09 2015 Subject: [squeak-dev] Re: SelectionMorph send to back In-Reply-To: References: <554BB391.4020707@stack.nl> Message-ID: 2015-05-08 13:28 GMT+02:00 Stephan Eggermont : > On 07/05/15 21:05, karl ramberg wrote: > >> SelectionMorph does not have a owner. >> Method should probably be something like >> >> SelectionMorph>>goBehind >> ActiveWorld addMorphNearBack: self. >> > > Does it actually need to do anything? > It responds true to wantsToBeTopmost. > delegate to the selected items? SelectionMorph>>goBehind self selectedItems do:[:d | d goBehind]. > > Stephan > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/9fdefffb/attachment.htm From craig at netjam.org Fri May 8 13:30:35 2015 From: craig at netjam.org (Craig Latta) Date: Fri May 8 13:30:47 2015 Subject: [squeak-dev] re: Pending OS-X Cocoa Squeak VM build In-Reply-To: References: Message-ID: > I've taken some time to integrate various Pharo and Pyonkee changes > into the Squeak OS-X and iOS cocoa source tree, along with converting > the code base to ARC and modern Obj-C. > > ... > > Shortly I will be integrating these changes into the Cog branch and > create an XCode project for building a 64/64 Cog/etc VM. Thanks! -C -- Craig Latta netjam.org +31 6 2757 7177 (SMS ok) + 1 415 287 3547 (no SMS) From karlramberg at gmail.com Fri May 8 13:47:26 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri May 8 13:47:29 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: <1431083128070-4825254.post@n4.nabble.com> References: <1431083128070-4825254.post@n4.nabble.com> Message-ID: If the model for the searchString in MessageNames was StringHolder instead of ValueHolder it would be easy to add menus. Is there a specific reason to use ValueHolder as model? Karl On Fri, May 8, 2015 at 1:05 PM, marcel.taeumel wrote: > Not easily... > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4825254.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/8722111c/attachment.htm From commits at source.squeak.org Fri May 8 14:11:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 14:11:52 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.972.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.972.mcz ==================== Summary ==================== Name: Morphic-mt.972 Author: mt Time: 8 May 2015, 4:11:13.964 pm UUID: 62836d59-3f13-db44-bf59-bc9e0f1a6240 Ancestors: Morphic-mt.971 Hide custom drop shadow in menus if those are being dragged around. (Increases visual compatibility with soft drop shadows.) =============== Diff against Morphic-mt.971 =============== Item was changed: ----- Method: MenuMorph>>justDroppedInto:event: (in category 'dropping/grabbing') ----- justDroppedInto: aMorph event: evt | halo | super justDroppedInto: aMorph event: evt. halo := evt hand halo. (halo notNil and:[halo target hasOwner: self]) ifTrue:[ "Grabbed single menu item" self addHalo: evt. ]. + stayUp ifFalse:[evt hand newMouseFocus: self]. + self hasDropShadow: Preferences menuAppearance3d.! - stayUp ifFalse:[evt hand newMouseFocus: self].! Item was changed: ----- Method: MenuMorph>>mouseDown: (in category 'events') ----- mouseDown: evt "Handle a mouse down event." (stayUp or:[self fullContainsPoint: evt position]) ifFalse:[^self deleteIfPopUp: evt]. "click outside" self isSticky ifTrue: [^self]. + "Grab the menu and drag it to some other place" + self hasDropShadow: false. evt hand grabMorph: self.! From commits at source.squeak.org Fri May 8 14:13:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 14:13:08 2015 Subject: [squeak-dev] The Trunk: Morphic-topa.973.mcz Message-ID: Tobias Pape uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-topa.973.mcz ==================== Summary ==================== Name: Morphic-topa.973 Author: topa Time: 8 May 2015, 4:12:31.467 pm UUID: 94308b91-2a2c-46b1-b880-3fa2ca75b1b5 Ancestors: Morphic-mt.972 Default to international time format. =============== Diff against Morphic-mt.972 =============== Item was changed: ----- Method: TheWorldMainDockingBar>>clockOn: (in category 'right side') ----- clockOn: aDockingBar aDockingBar + addMorphBack: (ClockMorph new show24hr: true; yourself); - addMorphBack: ClockMorph new ; addDefaultSpace! From commits at source.squeak.org Fri May 8 14:19:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 14:19:30 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.974.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.974.mcz ==================== Summary ==================== Name: Morphic-mt.974 Author: mt Time: 8 May 2015, 4:18:52.877 pm UUID: 6eeb73ef-2f37-4b4c-b686-f06aa396fff2 Ancestors: Morphic-topa.973 Remove drop shadow when dragging dialog boxes. =============== Diff against Morphic-topa.973 =============== Item was changed: ----- Method: UserDialogBoxMorph>>initialize (in category 'initialization') ----- initialize | titleRow cc | super initialize. self color: Color white. self listDirection: #topToBottom; wrapCentering: #center; hResizing: #shrinkWrap; vResizing: #shrinkWrap. self layoutInset: -1 @ -1; cellInset: 5@5. self borderStyle: BorderStyle thinGray. + self setProperty: #indicateKeyboardFocus: toValue: #never. FillInTheBlankMorph roundedDialogCorners ifTrue: [self useRoundedCorners]. self hasDropShadow: Preferences menuAppearance3d. self useSoftDropShadow ifFalse: [ self shadowColor: (TranslucentColor r: 0.0 g: 0.0 b: 0.0 alpha: 0.666); shadowOffset: 1 @ 1] ifTrue: [ self shadowColor: (TranslucentColor r: 0.0 g: 0.0 b: 0.0 alpha: 0.01); shadowOffset: (10@8 corner: 10@12)]. cc := Color gray: 0.8. titleRow := AlignmentMorph newRow. titleRow hResizing: #spaceFill; vResizing: #shrinkWrap. self cornerStyle == #rounded ifTrue: [titleRow useRoundedCorners]. titleRow borderStyle: BorderStyle thinGray. titleRow layoutInset: (5@5 corner: (2@ (5 + (titleRow cornerStyle == #rounded ifTrue: [Morph preferredCornerRadius] ifFalse: [0])))). titleRow color: cc. titleRow fillStyle: self titleGradient. titleMorph := StringMorph new. titleMorph emphasis: 1. titleRow addMorph: titleMorph. labelMorph := TextMorph new. labelMorph margins: (Preferences standardButtonFont widthOf: $x) * 2 @ 0. labelMorph lock. buttonRow := AlignmentMorph newRow vResizing: #rigid; height: (Preferences standardButtonFont height + 20); hResizing: #spaceFill; layoutInset: (((Preferences standardButtonFont widthOf: $x) * 2 @ 0) corner: ((Preferences standardButtonFont widthOf: $x) * 2 @ 10)); cellInset: (Preferences standardButtonFont widthOf: $x) * 2. buttonRow color: Color transparent. self addMorphBack: titleRow ; addMorphBack: labelMorph ; addMorphBack: buttonRow. keyMap := Dictionary new! Item was changed: ----- Method: UserDialogBoxMorph>>justDroppedInto:event: (in category 'events') ----- justDroppedInto: aMorph event: event + + "Restore drop shadow if necessary." + self hasDropShadow: Preferences menuAppearance3d. + "aggressively preserve focus" event hand newMouseFocus: self.! Item was changed: ----- Method: UserDialogBoxMorph>>mouseDown: (in category 'events') ----- mouseDown: event self stopAutoTrigger. "Always bring me to the front since I am modal" self comeToFront. (self containsPoint: event position) ifFalse:[ Beeper beepPrimitive. ^self flash]. + + self hasDropShadow: false. event hand grabMorph: self.! From eliot.miranda at gmail.com Fri May 8 14:22:01 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 8 14:22:59 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: <20150508021949.GA7296@shell.msen.com> References: <20150508021949.GA7296@shell.msen.com> Message-ID: Hi David, it is always possible to fix it another way but it would be hugely expensive. The only affordable way I know is to delete the existing files and upload new ones. Can someone who has access to the box simply login with either ash or FTP and delete them with a single command? If I had access to the box that is what I would do. Eliot (phone) On May 7, 2015, at 7:19 PM, "David T. Lewis" wrote: > On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >> Hi All, >> >> I need to delete all the patched Spur packages in trunk to ensure that >> correctly patched versions replace them. Is there an automated way of >> deleting packages on trunk? I've used the web interface, but it'll take >> all day :-( >> -- >> best, >> Eliot > > I don't know the answer to your question, but if I look at the files in > the squeaksource repository, there are quite a few: > > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz | wc -l > 246 > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd | wc -l > 152 > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm | wc -l > 33 > davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | wc -l > 450 > > Is it really necessary to delete all of this stuff? Or could we keep it as is, and > work around the problems in some other way? > > Dave > > > From eliot.miranda at gmail.com Fri May 8 14:24:42 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 8 14:25:38 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> Message-ID: <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> Hi David, and to be very clear, the *only* packages to be deleted are those matching Collections.spur* Compiler.spur* Kernel.spur* System.spur* Eliot (phone) On May 8, 2015, at 7:22 AM, Eliot Miranda wrote: > Hi David, > > it is always possible to fix it another way but it would be hugely expensive. The only affordable way I know is to delete the existing files and upload new ones. Can someone who has access to the box simply login with either ash or FTP and delete them with a single command? If I had access to the box that is what I would do. > > Eliot (phone) > > On May 7, 2015, at 7:19 PM, "David T. Lewis" wrote: > >> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >>> Hi All, >>> >>> I need to delete all the patched Spur packages in trunk to ensure that >>> correctly patched versions replace them. Is there an automated way of >>> deleting packages on trunk? I've used the web interface, but it'll take >>> all day :-( >>> -- >>> best, >>> Eliot >> >> I don't know the answer to your question, but if I look at the files in >> the squeaksource repository, there are quite a few: >> >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz | wc -l >> 246 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd | wc -l >> 152 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm | wc -l >> 33 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | wc -l >> 450 >> >> Is it really necessary to delete all of this stuff? Or could we keep it as is, and >> work around the problems in some other way? >> >> Dave >> >> >> From commits at source.squeak.org Fri May 8 14:27:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 14:27:27 2015 Subject: [squeak-dev] The Trunk: ReleaseBuilder-topa.122.mcz Message-ID: Tobias Pape uploaded a new version of ReleaseBuilder to project The Trunk: http://source.squeak.org/trunk/ReleaseBuilder-topa.122.mcz ==================== Summary ==================== Name: ReleaseBuilder-topa.122 Author: topa Time: 8 May 2015, 4:27:14.913 pm UUID: 82b7b6ca-da11-4663-ade1-1a3882287a11 Ancestors: ReleaseBuilder-kfr.121 Tweak the OOBE (proposal) =============== Diff against ReleaseBuilder-kfr.121 =============== Item was changed: ----- Method: ReleaseBuilder class>>setPreferences46 (in category 'preferences') ----- setPreferences46 "Preferences class defaultValueTableForCurrentRelease" + self setProjectBackground: Color darkGray. + - self setProjectBackground: self projectBackground46. - "General User interaction" Preferences + enable: #swapMouseButtons; + disable: #mouseOverForKeyboardFocus. - disable: #swapMouseButtons; - enable: #mouseOverForKeyboardFocus. Morph indicateKeyboardFocus: true. "Text input." TextEditor autoEnclose: false ; autoIndent: true ; destructiveBackWord: false ; blinkingCursor: true ; dumbbellCursor: false. Preferences insertionPointColor: Color red. PluggableTextMorph simpleFrameAdornments: false. "Windows" + Preferences installUniformWindowColors. - Preferences installNormalWindowColors. SystemWindow reuseWindows: false. Model windowActiveOnFirstClick: false. "Not good for 800x600" + Preferences + disable: #showSplitterHandles; + enable: #fastDragWindowForMorphic. - Preferences disable: #showSplitterHandles. CornerGripMorph drawCornerResizeHandles: false. ProportionalSplitterMorph smartHorizontalSplitters: false ; smartVerticalSplitters: false. "Scroll bars." Preferences enable: #scrollBarsNarrow; enable: #scrollBarsOnRight; disable: #alwaysHideHScrollbar; disable: #alwaysShowHScrollbar; disable: #alwaysShowVScrollbar. ScrollBar scrollBarsWithoutArrowButtons: true; scrollBarsWithoutMenuButton: true. ScrollPane useRetractableScrollBars: false. "Rounded corners." Morph preferredCornerRadius: 6. Preferences disable: #roundedWindowCorners. PluggableButtonMorph roundedButtonCorners: false. FillInTheBlankMorph roundedDialogCorners: false. MenuMorph roundedMenuCorners: false. ScrollBar roundedScrollBarLook: false. "Gradients." Preferences disable: #gradientScrollBars. SystemWindow gradientWindow: false. MenuMorph gradientMenu: false. PluggableButtonMorph gradientButton: false. "Shadows" Preferences enable: #menuAppearance3d. + MenuMorph + menuBorderWidth: 1; + menuBorderColor: Color lightGray; + menuLineColor: Color lightGray. + Morph useSoftDropShadow: true.. - Morph useSoftDropShadow: true. "Lists and Trees" PluggableListMorph filterableLists: true; clearFilterAutomatically: false; highlightHoveredRow: true; menuRequestUpdatesSelection: true. PluggableTreeMorph filterByLabelsOnly: false; maximumSearchDepth: 1. LazyListMorph listSelectionTextColor: Color black; listSelectionColor: (Color r: 0.72 g: 0.72 b: 0.9). "Standard Tools" BalloonMorph setBalloonColorTo: (TranslucentColor r: 0.92 g: 0.92 b: 0.706 alpha: 0.75). Workspace shouldStyle: false. Browser listClassesHierarchically: true; showClassIcons: true; showMessageIcons: true; sortMessageCategoriesAlphabetically: true. + Preferences enable: #annotationPanes; + enable: #optionalButtons; + enable: #diffsWithPrettyPrint; + enable: #traceMessages; + enable: #alternativeBrowseIt; + enable: #menuWithIcons; + enable: #visualExplorer. + SystemNavigation thoroughSenders: true. - Preferences - enable: #annotationPanes; - enable: #optionalButtons; - enable: #diffsWithPrettyPrint; - enable: #traceMessages ; - enable: #alternativeBrowseIt; - enable: #menuWithIcons; - enable: #visualExplorer. - SystemNavigation thoroughSenders: true. "Halo" Preferences enable: #showBoundsInHalo ; disable: #alternateHandlesLook. + "System" - "Network" NetNameResolver enableIPv6: false. + Scanner + allowUnderscoreAsAssignment: true; + prefAllowUnderscoreSelectors: true. + + "that's all, folks"! - - ! From karlramberg at gmail.com Fri May 8 14:51:37 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri May 8 14:51:39 2015 Subject: [squeak-dev] HelpBrowser search question Message-ID: When you search in the HelpBrowser it automatically also searches on the Wiki for answers. That is really nice. But it would also be nice to search online all the time. I wonder if we should have a check box to select if we want to include search online (wiki) or not ? Karl -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/fdc20003/attachment.htm From karlramberg at gmail.com Fri May 8 14:53:20 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri May 8 14:53:23 2015 Subject: [squeak-dev] Re: HelpBrowser search question In-Reply-To: References: Message-ID: Correction: But it would also be nice to *NOT* search online all the time. On Fri, May 8, 2015 at 4:51 PM, karl ramberg wrote: > When you search in the HelpBrowser it automatically also searches on the > Wiki for answers. That is really nice. But it would also be nice to search > online all the time. > > I wonder if we should have a check box to select if we want to include > search online (wiki) or not ? > > Karl > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/fb9562a9/attachment.htm From Marcel.Taeumel at hpi.de Fri May 8 14:41:16 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Fri May 8 14:57:20 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: References: <1431083128070-4825254.post@n4.nabble.com> Message-ID: <1431096076075-4825304.post@n4.nabble.com> Good idea, but if you set #contents: in a StringHolder, it does not tell it's dependents about the changed contents. ;-) Scary. But that's how it is. Not usable as a model except when subclassing and extending it. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4825304.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Fri May 8 14:43:37 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Fri May 8 14:59:39 2015 Subject: [squeak-dev] Re: HelpBrowser search question In-Reply-To: References: Message-ID: <1431096217863-4825306.post@n4.nabble.com> I guess we could add a preference whether to include the Squeak Wiki in the default help browser or not. Or two menu entries in the world main docking bar. Wiki search is also experimental. We could remove that wiki topic from the default help browser for the release... Best, Marcel -- View this message in context: http://forum.world.st/HelpBrowser-search-question-tp4825301p4825306.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Das.Linux at gmx.de Fri May 8 15:01:15 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri May 8 15:01:19 2015 Subject: [squeak-dev] Re: HelpBrowser search question In-Reply-To: <1431096217863-4825306.post@n4.nabble.com> References: <1431096217863-4825306.post@n4.nabble.com> Message-ID: On 08.05.2015, at 16:43, marcel.taeumel wrote: > I guess we could add a preference whether to include the Squeak Wiki in the > default help browser or not. Or two menu entries in the world main docking > bar. > > Wiki search is also experimental. We could remove that wiki topic from the > default help browser for the release... Yes Please > > Best, > Marcel From karlramberg at gmail.com Fri May 8 15:20:36 2015 From: karlramberg at gmail.com (karl ramberg) Date: Fri May 8 15:20:39 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: <1431096076075-4825304.post@n4.nabble.com> References: <1431083128070-4825254.post@n4.nabble.com> <1431096076075-4825304.post@n4.nabble.com> Message-ID: Ok On Fri, May 8, 2015 at 4:41 PM, marcel.taeumel wrote: > Good idea, but if you set #contents: in a StringHolder, it does not tell > it's > dependents about the changed contents. ;-) Scary. But that's how it is. Not > usable as a model except when subclassing and extending it. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4825304.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/ab97713c/attachment.htm From cunningham.cb at gmail.com Fri May 8 15:30:29 2015 From: cunningham.cb at gmail.com (Chris Cunningham) Date: Fri May 8 15:30:32 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: <1431096076075-4825304.post@n4.nabble.com> References: <1431083128070-4825254.post@n4.nabble.com> <1431096076075-4825304.post@n4.nabble.com> Message-ID: On Fri, May 8, 2015 at 7:41 AM, marcel.taeumel wrote: > Good idea, but if you set #contents: in a StringHolder, it does not tell > it's > dependents about the changed contents. Is this a good thing, or should that change? > ;-) Scary. But that's how it is. Not > usable as a model except when subclassing and extending it. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4825304.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/f7e4e0ae/attachment.htm From asqueaker at gmail.com Fri May 8 15:38:39 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri May 8 15:38:42 2015 Subject: [squeak-dev] The Trunk: Tools-mt.622.mcz In-Reply-To: <554c7b6d.210f340a.3a1e.ffff80c1SMTPIN_ADDED_MISSING@mx.google.com> References: <554c7b6d.210f340a.3a1e.ffff80c1SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Whoa, I can no longer simply press Return to search..? How does the "multi-line search pattern" work? On Fri, May 8, 2015 at 4:01 AM, wrote: > Marcel Taeumel uploaded a new version of Tools to project The Trunk: > http://source.squeak.org/trunk/Tools-mt.622.mcz > > ==================== Summary ==================== > > Name: Tools-mt.622 > Author: mt > Time: 8 May 2015, 11:01:04.067 am > UUID: d6bbe089-6caa-bb48-8823-ac746a9fc3f1 > Ancestors: Tools-mt.621 > > Fixed regression in Message Names tool. Support multi-line search pattern input again. > > =============== Diff against Tools-mt.621 =============== > > Item was changed: > ----- Method: MessageNames>>buildSearchPaneWith: (in category 'toolbuilder') ----- > buildSearchPaneWith: builder > > | panelSpec textSpec buttonSpec | > panelSpec := builder pluggablePanelSpec new > layout: #horizontal; > children: OrderedCollection new; > yourself. > > + textSpec := builder pluggableTextSpec new. > - textSpec := builder pluggableInputFieldSpec new. > textSpec > model: searchString; > help: 'Type here, then hit Search.' translated; > getText: #contents; > setText: #contents:. > panelSpec children add: textSpec. > > buttonSpec := builder pluggableActionButtonSpec new. > buttonSpec > model: self; > label: 'Search'; > action: #doSearch; > horizontalResizing: #shrinkWrap. > panelSpec children add: buttonSpec. > > ^ panelSpec! > > Item was changed: > ----- Method: MessageNames>>buildWith: (in category 'toolbuilder') ----- > buildWith: builder > "ToolBuilder open: MessageNames new" > > | windowSpec max searchHeight | > max := self wantsOptionalButtons ifTrue:[0.42] ifFalse:[0.5]. > searchHeight := Preferences standardDefaultTextFont height * 2. > > windowSpec := self buildWindowWith: builder specs: { > + (0@0 corner: 0.5@0.1) -> [self buildSearchPaneWith: builder]. > + (0@0.1 corner: 0.5 @ max) -> [self buildSelectorListWith: builder]. > - (self topConstantHeightFrame: searchHeight fromLeft: 0 width: 0.5) -> [self buildSearchPaneWith: builder]. > - (self frameOffsetFromTop: searchHeight fromLeft: 0 width: 0.5 bottomFraction: max) -> [self buildSelectorListWith: builder]. > (0.5@0.0 corner: 1.0@max) -> [self buildMessageListWith: builder]. > (0@max corner: 1@1) -> [self buildCodePaneWith: builder]. > }. > > ^ builder build: windowSpec! > > From lewis at mail.msen.com Fri May 8 16:03:55 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri May 8 16:03:56 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> Message-ID: <25639.136.2.1.102.1431101035.squirrel@webmail.msen.com> Hi Eliot, See also the reply from Tobias: > There are ways to do that; with access to the sso-image, it would take me > roughly an hour to two do that cleanly. > > Best regards > -Tobias Yes I have access and could delete the files, but it needs to be done cleanly as Tobias says because the SS image has all of the information, and the files are really just backing the image up. I am away and cannot do anything until tomorrow, but I would rather defer to Tobias on this one, as he is more knowledgeable about SS overall. Tobias, I think we need to give you an account on box4. Levente (box-admins lead) can do this, or I can do it tomorrow. Note - there is a #box-admin channel on Slack that is helpful for handling issues like this (as well as the box-admins list). Dave > Hi David, > > it is always possible to fix it another way but it would be hugely > expensive. The only affordable way I know is to delete the existing > files and upload new ones. Can someone who has access to the box > simply login with either ash or FTP and delete them with a single > command? If I had access to the box that is what I would do. > > Eliot (phone) > > On May 7, 2015, at 7:19 PM, "David T. Lewis" wrote: > >> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >>> Hi All, >>> >>> I need to delete all the patched Spur packages in trunk to ensure >>> that >>> correctly patched versions replace them. Is there an automated way of >>> deleting packages on trunk? I've used the web interface, but it'll >>> take >>> all day :-( >>> -- >>> best, >>> Eliot >> >> I don't know the answer to your question, but if I look at the files in >> the squeaksource repository, there are quite a few: >> >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz >> | wc -l >> 246 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd >> | wc -l >> 152 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm >> | wc -l >> 33 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | >> wc -l >> 450 >> >> Is it really necessary to delete all of this stuff? Or could we keep it >> as is, and >> work around the problems in some other way? >> >> Dave >> >> >> > From Das.Linux at gmx.de Fri May 8 16:36:37 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri May 8 16:36:41 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: <25639.136.2.1.102.1431101035.squirrel@webmail.msen.com> References: <20150508021949.GA7296@shell.msen.com> <25639.136.2.1.102.1431101035.squirrel@webmail.msen.com> Message-ID: <0B3B2861-523E-4BA5-9DF0-909E006F90BB@gmx.de> Hi, On 08.05.2015, at 18:03, David T. Lewis wrote: > Hi Eliot, > > See also the reply from Tobias: > >> There are ways to do that; with access to the sso-image, it would take me >> roughly an hour to two do that cleanly. >> >> Best regards >> -Tobias > > Yes I have access and could delete the files, but it needs to be done > cleanly as Tobias says because the SS image has all of the information, > and the files are really just backing the image up. > > I am away and cannot do anything until tomorrow, but I would rather defer > to Tobias on this one, as he is more knowledgeable about SS overall. > > Tobias, I think we need to give you an account on box4. Levente > (box-admins lead) can do this, or I can do it tomorrow. I already have :D Best regards -Tobias > > Note - there is a #box-admin channel on Slack that is helpful for handling > issues like this (as well as the box-admins list). > > Dave > > >> Hi David, >> >> it is always possible to fix it another way but it would be hugely >> expensive. The only affordable way I know is to delete the existing >> files and upload new ones. Can someone who has access to the box >> simply login with either ash or FTP and delete them with a single >> command? If I had access to the box that is what I would do. >> >> Eliot (phone) >> >> On May 7, 2015, at 7:19 PM, "David T. Lewis" wrote: >> >>> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >>>> Hi All, >>>> >>>> I need to delete all the patched Spur packages in trunk to ensure >>>> that >>>> correctly patched versions replace them. Is there an automated way of >>>> deleting packages on trunk? I've used the web interface, but it'll >>>> take >>>> all day :-( >>>> -- >>>> best, >>>> Eliot >>> >>> I don't know the answer to your question, but if I look at the files in >>> the squeaksource repository, there are quite a few: >>> >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz >>> | wc -l >>> 246 >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd >>> | wc -l >>> 152 >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm >>> | wc -l >>> 33 >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | >>> wc -l >>> 450 >>> >>> Is it really necessary to delete all of this stuff? Or could we keep it >>> as is, and >>> work around the problems in some other way? >>> >>> Dave From eliot.miranda at gmail.com Fri May 8 17:26:43 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 8 17:26:46 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: <0B3B2861-523E-4BA5-9DF0-909E006F90BB@gmx.de> References: <20150508021949.GA7296@shell.msen.com> <25639.136.2.1.102.1431101035.squirrel@webmail.msen.com> <0B3B2861-523E-4BA5-9DF0-909E006F90BB@gmx.de> Message-ID: Hi Tobias, On Fri, May 8, 2015 at 9:36 AM, Tobias Pape wrote: > Hi, > > On 08.05.2015, at 18:03, David T. Lewis wrote: > > > Hi Eliot, > > > > See also the reply from Tobias: > > > >> There are ways to do that; with access to the sso-image, it would take > me > >> roughly an hour to two do that cleanly. > >> > >> Best regards > >> -Tobias > > > > Yes I have access and could delete the files, but it needs to be done > > cleanly as Tobias says because the SS image has all of the information, > > and the files are really just backing the image up. > > > > I am away and cannot do anything until tomorrow, but I would rather defer > > to Tobias on this one, as he is more knowledgeable about SS overall. > > > > Tobias, I think we need to give you an account on box4. Levente > > (box-admins lead) can do this, or I can do it tomorrow. > > I already have :D > The Collections.spur, Compiler.spur, Kernel.spur and Syste,.spur files are still on the repository. Did you mean you already have permission or you already have deleted the files? I'd like them deleted asap. Can we perhaps meet (e.g. on Skype) to effect this? Thanks! > > > Best regards > -Tobias > > > > Note - there is a #box-admin channel on Slack that is helpful for > handling > > issues like this (as well as the box-admins list). > > > > > > Dave > > > > > >> Hi David, > >> > >> it is always possible to fix it another way but it would be hugely > >> expensive. The only affordable way I know is to delete the existing > >> files and upload new ones. Can someone who has access to the box > >> simply login with either ash or FTP and delete them with a single > >> command? If I had access to the box that is what I would do. > >> > >> Eliot (phone) > >> > >> On May 7, 2015, at 7:19 PM, "David T. Lewis" > wrote: > >> > >>> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: > >>>> Hi All, > >>>> > >>>> I need to delete all the patched Spur packages in trunk to ensure > >>>> that > >>>> correctly patched versions replace them. Is there an automated way of > >>>> deleting packages on trunk? I've used the web interface, but it'll > >>>> take > >>>> all day :-( > >>>> -- > >>>> best, > >>>> Eliot > >>> > >>> I don't know the answer to your question, but if I look at the files in > >>> the squeaksource repository, there are quite a few: > >>> > >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls > *spur*mcz > >>> | wc -l > >>> 246 > >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls > *spur*mcd > >>> | wc -l > >>> 152 > >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls > *spur*mcm > >>> | wc -l > >>> 33 > >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | > >>> wc -l > >>> 450 > >>> > >>> Is it really necessary to delete all of this stuff? Or could we keep it > >>> as is, and > >>> work around the problems in some other way? > >>> > >>> Dave > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/1b5d483a/attachment.htm From leves at elte.hu Fri May 8 21:17:55 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri May 8 21:17:59 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> Message-ID: Hi Eliot, If you can generate the files while they are in the repository (on the server), then you can save the time waiting for someone to delete them, because while you can't delete the files from the server, you can overwrite them. This wouldn't help with the .mcds, but I think those are not cached in the image, so deleting just the .mcds is probably a way easier thing to do. Levente On Fri, 8 May 2015, Eliot Miranda wrote: > Hi David, > > and to be very clear, the *only* packages to be deleted are those matching > > Collections.spur* > Compiler.spur* > Kernel.spur* > System.spur* > > Eliot (phone) > > On May 8, 2015, at 7:22 AM, Eliot Miranda wrote: > >> Hi David, >> >> it is always possible to fix it another way but it would be hugely expensive. The only affordable way I know is to delete the existing files and upload new ones. Can someone who has access to the box simply login with either ash or FTP and delete them with a single command? If I had access to the box that is what I would do. >> >> Eliot (phone) >> >> On May 7, 2015, at 7:19 PM, "David T. Lewis" wrote: >> >>> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >>>> Hi All, >>>> >>>> I need to delete all the patched Spur packages in trunk to ensure that >>>> correctly patched versions replace them. Is there an automated way of >>>> deleting packages on trunk? I've used the web interface, but it'll take >>>> all day :-( >>>> -- >>>> best, >>>> Eliot >>> >>> I don't know the answer to your question, but if I look at the files in >>> the squeaksource repository, there are quite a few: >>> >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz | wc -l >>> 246 >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd | wc -l >>> 152 >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm | wc -l >>> 33 >>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | wc -l >>> 450 >>> >>> Is it really necessary to delete all of this stuff? Or could we keep it as is, and >>> work around the problems in some other way? >>> >>> Dave >>> >>> >>> > > From Das.Linux at gmx.de Fri May 8 21:26:36 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri May 8 21:26:40 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> Message-ID: On 08.05.2015, at 23:17, Levente Uzonyi wrote: > Hi Eliot, > > If you can generate the files while they are in the repository (on the server), then you can save the time waiting for someone to delete them, because while you can't delete the files from the server, you can overwrite them. To my knowledge, you can't. > This wouldn't help with the .mcds, but I think those are not cached in the image, so deleting just the .mcds is probably a way easier thing to do. > Best regards -Tobias > Levente > > On Fri, 8 May 2015, Eliot Miranda wrote: > >> Hi David, >> >> and to be very clear, the *only* packages to be deleted are those matching >> >> Collections.spur* >> Compiler.spur* >> Kernel.spur* >> System.spur* >> >> Eliot (phone) >> >> On May 8, 2015, at 7:22 AM, Eliot Miranda wrote: >> >>> Hi David, >>> >>> it is always possible to fix it another way but it would be hugely expensive. The only affordable way I know is to delete the existing files and upload new ones. Can someone who has access to the box simply login with either ash or FTP and delete them with a single command? If I had access to the box that is what I would do. >>> >>> Eliot (phone) >>> >>> On May 7, 2015, at 7:19 PM, "David T. Lewis" wrote: >>> >>>> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >>>>> Hi All, >>>>> >>>>> I need to delete all the patched Spur packages in trunk to ensure that >>>>> correctly patched versions replace them. Is there an automated way of >>>>> deleting packages on trunk? I've used the web interface, but it'll take >>>>> all day :-( >>>>> -- >>>>> best, >>>>> Eliot >>>> >>>> I don't know the answer to your question, but if I look at the files in >>>> the squeaksource repository, there are quite a few: >>>> >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz | wc -l >>>> 246 >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd | wc -l >>>> 152 >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm | wc -l >>>> 33 >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | wc -l >>>> 450 >>>> >>>> Is it really necessary to delete all of this stuff? Or could we keep it as is, and >>>> work around the problems in some other way? >>>> >>>> Dave From eliot.miranda at gmail.com Fri May 8 21:35:37 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 8 21:35:40 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> Message-ID: Hi Levente, On Fri, May 8, 2015 at 2:17 PM, Levente Uzonyi wrote: > Hi Eliot, > > If you can generate the files while they are in the repository (on the > server), then you can save the time waiting for someone to delete them, > because while you can't delete the files from the server, you can overwrite > them. This wouldn't help with the .mcds, but I think those are not cached > in the image, so deleting just the .mcds is probably a way easier thing to > do. I thought this too. But when I tried doing this yesterday, and earlier, the files were not replaced. I have a generated set waiting to upload as soon as the old ones have been deleted. > > Levente > > > On Fri, 8 May 2015, Eliot Miranda wrote: > > Hi David, >> >> and to be very clear, the *only* packages to be deleted are those >> matching >> >> Collections.spur* >> Compiler.spur* >> Kernel.spur* >> System.spur* >> >> Eliot (phone) >> >> On May 8, 2015, at 7:22 AM, Eliot Miranda >> wrote: >> >> Hi David, >>> >>> it is always possible to fix it another way but it would be hugely >>> expensive. The only affordable way I know is to delete the existing files >>> and upload new ones. Can someone who has access to the box simply login >>> with either ash or FTP and delete them with a single command? If I had >>> access to the box that is what I would do. >>> >>> Eliot (phone) >>> >>> On May 7, 2015, at 7:19 PM, "David T. Lewis" >>> wrote: >>> >>> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: >>>> >>>>> Hi All, >>>>> >>>>> I need to delete all the patched Spur packages in trunk to ensure >>>>> that >>>>> correctly patched versions replace them. Is there an automated way of >>>>> deleting packages on trunk? I've used the web interface, but it'll >>>>> take >>>>> all day :-( >>>>> -- >>>>> best, >>>>> Eliot >>>>> >>>> >>>> I don't know the answer to your question, but if I look at the files in >>>> the squeaksource repository, there are quite a few: >>>> >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls >>>> *spur*mcz | wc -l >>>> 246 >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls >>>> *spur*mcd | wc -l >>>> 152 >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls >>>> *spur*mcm | wc -l >>>> 33 >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | >>>> wc -l >>>> 450 >>>> >>>> Is it really necessary to delete all of this stuff? Or could we keep it >>>> as is, and >>>> work around the problems in some other way? >>>> >>>> Dave >>>> >>>> >>>> >>>> >> >> > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/112f4bc4/attachment.htm From eliot.miranda at gmail.com Fri May 8 21:36:04 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 8 21:36:06 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> Message-ID: On Fri, May 8, 2015 at 2:26 PM, Tobias Pape wrote: > > On 08.05.2015, at 23:17, Levente Uzonyi wrote: > > > Hi Eliot, > > > > If you can generate the files while they are in the repository (on the > server), then you can save the time waiting for someone to delete them, > because while you can't delete the files from the server, you can overwrite > them. > > To my knowledge, you can't. > +1. > > > This wouldn't help with the .mcds, but I think those are not cached in > the image, so deleting just the .mcds is probably a way easier thing to do. > > > > > Best regards > -Tobias > > > Levente > > > > On Fri, 8 May 2015, Eliot Miranda wrote: > > > >> Hi David, > >> > >> and to be very clear, the *only* packages to be deleted are those > matching > >> > >> Collections.spur* > >> Compiler.spur* > >> Kernel.spur* > >> System.spur* > >> > >> Eliot (phone) > >> > >> On May 8, 2015, at 7:22 AM, Eliot Miranda > wrote: > >> > >>> Hi David, > >>> > >>> it is always possible to fix it another way but it would be hugely > expensive. The only affordable way I know is to delete the existing files > and upload new ones. Can someone who has access to the box simply login > with either ash or FTP and delete them with a single command? If I had > access to the box that is what I would do. > >>> > >>> Eliot (phone) > >>> > >>> On May 7, 2015, at 7:19 PM, "David T. Lewis" > wrote: > >>> > >>>> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: > >>>>> Hi All, > >>>>> > >>>>> I need to delete all the patched Spur packages in trunk to ensure > that > >>>>> correctly patched versions replace them. Is there an automated way > of > >>>>> deleting packages on trunk? I've used the web interface, but it'll > take > >>>>> all day :-( > >>>>> -- > >>>>> best, > >>>>> Eliot > >>>> > >>>> I don't know the answer to your question, but if I look at the files > in > >>>> the squeaksource repository, there are quite a few: > >>>> > >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls > *spur*mcz | wc -l > >>>> 246 > >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls > *spur*mcd | wc -l > >>>> 152 > >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls > *spur*mcm | wc -l > >>>> 33 > >>>> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* > | wc -l > >>>> 450 > >>>> > >>>> Is it really necessary to delete all of this stuff? Or could we keep > it as is, and > >>>> work around the problems in some other way? > >>>> > >>>> Dave > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/39e736bd/attachment.htm From commits at source.squeak.org Fri May 8 21:40:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 21:40:46 2015 Subject: [squeak-dev] The Trunk: Collections-ul.625.mcz Message-ID: Levente Uzonyi uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-ul.625.mcz ==================== Summary ==================== Name: Collections-ul.625 Author: ul Time: 1 May 2015, 1:41:40.726 pm UUID: d09538cd-53f4-42d7-8070-224fde4a4ae2 Ancestors: Collections-ul.624 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. =============== Diff against Collections-ul.624 =============== Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + value > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: value + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: value)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + value > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: value + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: value)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + value > 255 ifFalse: [ ^((ClassificationTable at: value + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! From leves at elte.hu Fri May 8 21:42:19 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri May 8 21:42:24 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> Message-ID: Hi Eliot, On Fri, 8 May 2015, Eliot Miranda wrote: > Hi Levente, > On Fri, May 8, 2015 at 2:17 PM, Levente Uzonyi wrote: > Hi Eliot, > > If you can generate the files while they are in the repository (on the server), then you can save the time waiting for someone to > delete them, because while you can't delete the files from the server, you can overwrite them. This wouldn't help with the .mcds, but > I think those are not cached in the image, so deleting just the .mcds is probably a way easier thing to do. > > > I thought this too.? But when I tried doing this yesterday, and earlier, the files were not replaced.? I have a generated set waiting to upload as > soon as the old ones have been deleted. ? I just reuploaded Collections-ul.625.mcz, and the server happily accepted it. It even sent a mail about it. It's possible that it won't accept packages with different content, but it clearly accepts reuploads (which is a bug). Levente > > > > Levente > > On Fri, 8 May 2015, Eliot Miranda wrote: > > Hi David, > > ? ? and to be very clear, the *only* packages to be deleted are those matching > > Collections.spur* > Compiler.spur* > Kernel.spur* > System.spur* > > Eliot (phone) > > On May 8, 2015, at 7:22 AM, Eliot Miranda wrote: > > Hi David, > > ? ? it is always possible to fix it another way but it would be hugely expensive.? The only affordable way I > know is to delete the existing files and upload new ones.? Can someone who has access to the box simply login > with either ash or FTP and delete them with a single command?? If I had access to the box that is what I would > do. > > Eliot (phone) > > On May 7, 2015, at 7:19 PM, "David T. Lewis" wrote: > > On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot Miranda wrote: > Hi All, > > ? I need to delete all the patched Spur packages in trunk to ensure that > correctly patched versions replace them.? Is there an automated way of > deleting packages on trunk?? I've used the web interface, but it'll take > all day :-( > -- > best, > Eliot > > > I don't know the answer to your question, but if I look at the files in > the squeaksource repository, there are quite a few: > > ? davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcz | wc -l > ? 246 > ? davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcd | wc -l > ? 152 > ? davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur*mcm | wc -l > ? 33 > ? davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ ls *spur* | wc -l > ? 450 > > Is it really necessary to delete all of this stuff? Or could we keep it as is, and > work around the problems in some other way? > > Dave > > > > > > > > > > -- > best,Eliot > > From commits at source.squeak.org Fri May 8 21:55:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 8 21:55:09 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150508215506.12258.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008327.html Name: Tools-mt.622 Ancestors: Tools-mt.621 Fixed regression in Message Names tool. Support multi-line search pattern input again. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008328.html Name: Morphic-mt.970 Ancestors: Morphic-mt.969 Use a reduced minimum width fors buttons if they are #shrinkWrap. Better for lower resolutions resp. tool window sizes. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008329.html Name: Tools-mt.623 Ancestors: Tools-mt.622 Re-order instance/?/class switches in browsers to instance/class/? as discussed here: http://forum.world.st/Changing-button-groups-order-in-browsers-tp4823991.html Assumption: Switching between instance/class is used more often than ? . Also, instance/class are more cohesive but ? is something special. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008330.html Name: Tools-mt.624 Ancestors: Tools-mt.623 Some other regressions fixed in Message Names tool regarding selections. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008331.html Name: Morphic-mt.971 Ancestors: Morphic-mt.970 More workspace capabilities added to search bar. Old search bar morph deprecated. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008332.html Name: 46Deprecated-mt.3 Ancestors: 46Deprecated-mt.2 Old search bar morph added to keep that code in case of regression bugs with the new, toolbuilder-driven search bar. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008333.html Name: Morphic-mt.972 Ancestors: Morphic-mt.971 Hide custom drop shadow in menus if those are being dragged around. (Increases visual compatibility with soft drop shadows.) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008334.html Name: Morphic-topa.973 Ancestors: Morphic-mt.972 Default to international time format. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008335.html Name: Morphic-mt.974 Ancestors: Morphic-topa.973 Remove drop shadow when dragging dialog boxes. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008336.html Name: ReleaseBuilder-topa.122 Ancestors: ReleaseBuilder-kfr.121 Tweak the OOBE (proposal) ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008337.html Name: Collections-ul.625 Ancestors: Collections-ul.624 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. ============================================= From eliot.miranda at gmail.com Fri May 8 22:18:42 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 8 22:18:46 2015 Subject: [squeak-dev] automated way to delete specific trunk packages? In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> Message-ID: On Fri, May 8, 2015 at 2:42 PM, Levente Uzonyi wrote: > Hi Eliot, > > On Fri, 8 May 2015, Eliot Miranda wrote: > > Hi Levente, >> On Fri, May 8, 2015 at 2:17 PM, Levente Uzonyi wrote: >> Hi Eliot, >> >> If you can generate the files while they are in the repository (on >> the server), then you can save the time waiting for someone to >> delete them, because while you can't delete the files from the >> server, you can overwrite them. This wouldn't help with the .mcds, but >> I think those are not cached in the image, so deleting just the >> .mcds is probably a way easier thing to do. >> >> >> I thought this too. But when I tried doing this yesterday, and earlier, >> the files were not replaced. I have a generated set waiting to upload as >> soon as the old ones have been deleted. >> > > I just reuploaded Collections-ul.625.mcz, and the server happily accepted > it. It even sent a mail about it. > It's possible that it won't accept packages with different content, but it > clearly accepts reuploads (which is a bug). Well, yesterday I uploaded a correct version of Collections.spur-tfel.624 and the server appeared to accept it, but when I downloaded the package from the server i got the old package. So I don't know. I think the safest thing is to nuke the old packages and upload freshly patched ones. > > Levente > > > >> >> >> Levente >> >> On Fri, 8 May 2015, Eliot Miranda wrote: >> >> Hi David, >> >> and to be very clear, the *only* packages to be deleted >> are those matching >> >> Collections.spur* >> Compiler.spur* >> Kernel.spur* >> System.spur* >> >> Eliot (phone) >> >> On May 8, 2015, at 7:22 AM, Eliot Miranda < >> eliot.miranda@gmail.com> wrote: >> >> Hi David, >> >> it is always possible to fix it another way but it >> would be hugely expensive. The only affordable way I >> know is to delete the existing files and upload new >> ones. Can someone who has access to the box simply login >> with either ash or FTP and delete them with a single >> command? If I had access to the box that is what I would >> do. >> >> Eliot (phone) >> >> On May 7, 2015, at 7:19 PM, "David T. Lewis" < >> lewis@mail.msen.com> wrote: >> >> On Thu, May 07, 2015 at 04:58:55PM -0700, Eliot >> Miranda wrote: >> Hi All, >> >> I need to delete all the patched Spur >> packages in trunk to ensure that >> correctly patched versions replace them. >> Is there an automated way of >> deleting packages on trunk? I've used the >> web interface, but it'll take >> all day :-( >> -- >> best, >> Eliot >> >> >> I don't know the answer to your question, but if >> I look at the files in >> the squeaksource repository, there are quite a >> few: >> >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ >> ls *spur*mcz | wc -l >> 246 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ >> ls *spur*mcd | wc -l >> 152 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ >> ls *spur*mcm | wc -l >> 33 >> davidlewis@squeak-box4:/home/squeaksource/sso2/ss/trunk$ >> ls *spur* | wc -l >> 450 >> >> Is it really necessary to delete all of this >> stuff? Or could we keep it as is, and >> work around the problems in some other way? >> >> Dave >> >> >> >> >> >> >> >> >> >> -- >> best,Eliot >> >> > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150508/8d06388a/attachment-0001.htm From Marcel.Taeumel at hpi.de Sat May 9 14:16:16 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Sat May 9 14:32:25 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: References: Message-ID: <1431180976415-4825440.post@n4.nabble.com> You separate patterns with ";". Multi-line just because it now wraps again. Could you hit return in the past? I thought that's why the "Search" button was there. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4825440.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Sat May 9 19:32:04 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sat May 9 19:32:08 2015 Subject: [squeak-dev] A fast Transcript Message-ID: Hi Juan, I see that your new transcript is indeed much faster but is also not editable. I wonder if it would be possible to have the best of both worlds and arrange that, when active, the transcript is editable. For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then when the window was exited, reverted to the standard fast output mode. As you can infer I like having an editable transcript. I can do without it, because Squeak's slow transcript is indeed a PITA, but I'm not sure that speed need preclude editability. On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) < juanlists@jvuletich.org> wrote: > Hi Folks, > > (below) > > > Quoting Ben Coman : > > On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda >> wrote: >> >> >>> >>> On Sat, May 9, 2015 at 7:09 AM, Ben Coman wrote: >>> >>> From my limited experience bug hunting, calling #changed: from a thread >>>> other than the UI thread is a source of evil. There are too many >>>> assumptions throughout the system that the UI is single threaded. Can >>>> anyone advise me that is not a proper belief? >>>> >>>> Then that implies that a Transcript implementation where #nextPut: >>>> direct >>>> calls #changed: >>>> is not appropriate for use with multi-threaded applications. In Pharo, >>>> #changed: is only called from #stepGlobal, which is called from >>>> doOneCycle:. (This came about as a last minute bug fix before Pharo 3 >>>> release and maybe could use some cleanup. >>>> >>>> Separating the UI from Transcript into its own viewer might be a good >>>> idea, but actually it would not solve Stef's case since his code would >>>> still be running in the UI thread -- unless the viewer ran in another >>>> thread, which would have its own complexities. >>>> >>>> I think the point about efficiency is significant. The following >>>> example... >>>> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: 'x' >>>> ] ] >>>> on Squeak 4.5 --> 12749ms >>>> on Pharo 50029 --> 2ms >>>> >>>> This better performance helped me a lot trying to understand the high >>>> priority timerEventLoop being able to indiscriminately scatter >>>> Transcript >>>> tracing through that code. I believe its also probably beneficial for >>>> working with externally triggered semaphores and timing sensitive race >>>> conditions. >>>> >>>> So we have two mutually exclusive cases: >>>> * better interactivity, poorer system performance >>>> * faster system performance, worse interactivity >>>> >>>> Which of these is broken depends on your viewpoint. >>>> >>>> >>> Something that runs fast but is incorrect is still incorrect. The fact >>> that the transcript doesn't output until a world step is possible is a >>> bug. It forces programs that use the transcript to be rewritten in order >>> to see transcript output. >>> >>> >> As a point of comparison for correctness, for the following... >> >> Transcript clear. >> [ $a asciiValue to: $z asciiValue do: [ :c | >> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i >> printString , ' ' ] ] forkAt: 40 >> ]. >> ] forkAt: 41 >> >> Squeak 4.5 gives... >> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 >> $c4 >> $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 >> $h2 >> $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 >> $b7 >> $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 >> $u3 >> $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 >> $o4 >> $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 >> $m5 >> $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 >> $k6 >> $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 >> $l7 >> $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 >> $h8 >> $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 >> $f9 >> $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 >> $u9 >> $u9 $z9 $x9 >> >> Pharo 50041 gives... >> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 >> $c1 >> $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 >> $e2 >> $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 >> $g3 >> $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 >> $i4 >> $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 >> $k5 >> $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 >> $m6 >> $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 >> $o7 >> $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 >> $q8 >> $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 >> $s9 >> $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 >> $v1 >> $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 >> $x2 >> $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 >> $z3 >> $z4 $z5 $z6 $z7 $z8 $z9 >> >> (start your comparison at $b5) >> >> So in one axis Pharo has improved Transcript, but we didn't notice the >> significance of the use case we lost. >> >> cheers -ben >> > > Please take a good look at Cuis' Transcript and consider using it. > > By default, the display is updated immediately, but without calling > Morphic, it can even work with no UI framework at all. It does updates > faster than Squeak or Visualworks: > > Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: > 'x' ] ]. 763. > > But if you want minimum overhead without immediate feedback: > > Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 > timesRepeat: [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1. > "As fast as Pharo" > > It is also thread safe, and for Ben's example: > > Transcript clear. > [ > $a asciiValue to: $z asciiValue do: [ :c | > [ 1 to: 9 do: [ :i | Transcript show: c asCharacter > printString , i printString , ' ' ] ] forkAt: 40 > ]. > ] forkAt: 41 > > it gives the same result as Pharo. > > The fact that the updates are not bound to Morphic also means that it is > possible to do #show: deep in Morphic logic, without causing infinite loops > or recursions, and get immediate feedback. It has proved to be a useful aid > in debugging Morphic code. > > Cheers, > Juan Vuletich > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150509/afbbf855/attachment.htm From juanlists at jvuletich.org Sat May 9 21:11:11 2015 From: juanlists at jvuletich.org (J. Vuletich (mail lists)) Date: Sat May 9 21:11:15 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: References: Message-ID: <20150509211111.Horde.OkE4EqC9j_QL-_QL_e61Kg1@gator3294.hostgator.com> Hi Eliot, Yes, it is not editable. The approach you describe is a good idea. There are a few details to take care, like that the Cuis Transcript doesn't do wordwrap, and that's why it can work without the usual text editor machinery. So, maybe this editable Transcript should do no wordwrap, and have an horizontal scrollbar. Most likely there would be 2 models, one like the one in Cuis, that is just a collection of lines, and another that is a regular text model. So those would need to be sync'ed, etc. But it can be done and it would be great. Cheers, Juan Vuletich Quoting Eliot Miranda : > Hi Juan, > > I see that your new transcript is indeed much faster but is also not > editable. I wonder if it would be possible to have the best of both worlds > and arrange that, when active, the transcript is editable. For example, > selecting the TranscriptWIndow could put it into a mode where the > transcript's state was imported into a more conventional editable text > morph, and then when the window was exited, reverted to the standard fast > output mode. As you can infer I like having an editable transcript. I can > do without it, because Squeak's slow transcript is indeed a PITA, but I'm > not sure that speed need preclude editability. > > On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) < > juanlists@jvuletich.org> wrote: > >> Hi Folks, >> >> (below) >> >> >> Quoting Ben Coman : >> >> On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda >>> wrote: >>> >>> >>>> >>>> On Sat, May 9, 2015 at 7:09 AM, Ben Coman wrote: >>>> >>>> From my limited experience bug hunting, calling #changed: from a thread >>>>> other than the UI thread is a source of evil. There are too many >>>>> assumptions throughout the system that the UI is single threaded. Can >>>>> anyone advise me that is not a proper belief? >>>>> >>>>> Then that implies that a Transcript implementation where #nextPut: >>>>> direct >>>>> calls #changed: >>>>> is not appropriate for use with multi-threaded applications. In Pharo, >>>>> #changed: is only called from #stepGlobal, which is called from >>>>> doOneCycle:. (This came about as a last minute bug fix before Pharo 3 >>>>> release and maybe could use some cleanup. >>>>> >>>>> Separating the UI from Transcript into its own viewer might be a good >>>>> idea, but actually it would not solve Stef's case since his code would >>>>> still be running in the UI thread -- unless the viewer ran in another >>>>> thread, which would have its own complexities. >>>>> >>>>> I think the point about efficiency is significant. The following >>>>> example... >>>>> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: 'x' >>>>> ] ] >>>>> on Squeak 4.5 --> 12749ms >>>>> on Pharo 50029 --> 2ms >>>>> >>>>> This better performance helped me a lot trying to understand the high >>>>> priority timerEventLoop being able to indiscriminately scatter >>>>> Transcript >>>>> tracing through that code. I believe its also probably beneficial for >>>>> working with externally triggered semaphores and timing sensitive race >>>>> conditions. >>>>> >>>>> So we have two mutually exclusive cases: >>>>> * better interactivity, poorer system performance >>>>> * faster system performance, worse interactivity >>>>> >>>>> Which of these is broken depends on your viewpoint. >>>>> >>>>> >>>> Something that runs fast but is incorrect is still incorrect. The fact >>>> that the transcript doesn't output until a world step is possible is a >>>> bug. It forces programs that use the transcript to be rewritten in order >>>> to see transcript output. >>>> >>>> >>> As a point of comparison for correctness, for the following... >>> >>> Transcript clear. >>> [ $a asciiValue to: $z asciiValue do: [ :c | >>> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i >>> printString , ' ' ] ] forkAt: 40 >>> ]. >>> ] forkAt: 41 >>> >>> Squeak 4.5 gives... >>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 >>> $c4 >>> $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 >>> $h2 >>> $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 >>> $b7 >>> $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 >>> $u3 >>> $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 >>> $o4 >>> $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 >>> $m5 >>> $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 >>> $k6 >>> $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 >>> $l7 >>> $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 >>> $h8 >>> $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 >>> $f9 >>> $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 >>> $u9 >>> $u9 $z9 $x9 >>> >>> Pharo 50041 gives... >>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 >>> $c1 >>> $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 >>> $e2 >>> $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 >>> $g3 >>> $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 >>> $i4 >>> $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 >>> $k5 >>> $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 >>> $m6 >>> $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 >>> $o7 >>> $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 >>> $q8 >>> $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 >>> $s9 >>> $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 >>> $v1 >>> $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 >>> $x2 >>> $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 >>> $z3 >>> $z4 $z5 $z6 $z7 $z8 $z9 >>> >>> (start your comparison at $b5) >>> >>> So in one axis Pharo has improved Transcript, but we didn't notice the >>> significance of the use case we lost. >>> >>> cheers -ben >>> >> >> Please take a good look at Cuis' Transcript and consider using it. >> >> By default, the display is updated immediately, but without calling >> Morphic, it can even work with no UI framework at all. It does updates >> faster than Squeak or Visualworks: >> >> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: >> 'x' ] ]. 763. >> >> But if you want minimum overhead without immediate feedback: >> >> Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 >> timesRepeat: [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1. >> "As fast as Pharo" >> >> It is also thread safe, and for Ben's example: >> >> Transcript clear. >> [ >> $a asciiValue to: $z asciiValue do: [ :c | >> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter >> printString , i printString , ' ' ] ] forkAt: 40 >> ]. >> ] forkAt: 41 >> >> it gives the same result as Pharo. >> >> The fact that the updates are not bound to Morphic also means that it is >> possible to do #show: deep in Morphic logic, without causing infinite loops >> or recursions, and get immediate feedback. It has proved to be a useful aid >> in debugging Morphic code. >> >> Cheers, >> Juan Vuletich >> >> >> > > > -- > best, > Eliot From leves at elte.hu Sat May 9 23:06:32 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sat May 9 23:06:37 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: References: Message-ID: The main performance hog is the full redraw of the whole morph for every single #endEntry send. The morph re-renders all visible lines (see NewParagraph >> #displayOn:using:at:). If the visible lines' were cached on a form (probably one form per line), and only the newly added text were drawn during the update, then I think the performance would be similar to Cuis's implementation's, but without restrictions (text not selectable/editable). Levente On Sat, 9 May 2015, Eliot Miranda wrote: > Hi Juan, > ? ? I see that your new transcript is indeed much faster but is also not editable.? I wonder if it would be possible to have the best of both worlds and arrange that, when active, the transcript is editable.? > For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then when the window was exited, reverted to > the standard fast output mode.? As you can infer I like having an editable transcript.? I can do without it, because Squeak's slow transcript is indeed a PITA, but I'm not sure that speed need preclude > editability. > > On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) wrote: > Hi Folks, > > (below) > > Quoting Ben Coman : > > On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda > wrote: > > > > On Sat, May 9, 2015 at 7:09 AM, Ben Coman wrote: > > From my limited experience bug hunting, calling #changed: from a thread > other than the UI thread is a source of evil.? There are too many > assumptions throughout the system that the UI is single threaded.? Can > anyone advise me that is not a proper belief? > > Then that implies that a Transcript implementation where #nextPut: direct > calls #changed: > is not appropriate for use with multi-threaded applications.? In Pharo, > #changed: is only called from #stepGlobal, which is called from > doOneCycle:.? (This came about as a last minute bug fix before Pharo 3 > release and maybe could use some cleanup. > > Separating the UI from Transcript into its own viewer might be a good > idea, but actually it would not solve Stef's case since his code would > still be running in the UI thread -- unless the viewer ran in another > thread, which would have its own complexities. > > I think the point about efficiency is significant. The following > example... > ? ? ?Time millisecondsToRun: [ 1000 timesRepeat:? [ Transcript show: 'x' > ] ] > on Squeak 4.5 --> 12749ms > on Pharo 50029 --> 2ms > > This better performance helped me a lot trying to understand the high > priority timerEventLoop being able to indiscriminately scatter Transcript > tracing through that code.? I believe its also probably beneficial for > working with externally triggered semaphores and timing sensitive race > conditions. > > So we have two mutually exclusive cases: > * better interactivity, poorer system performance > * faster system performance, worse interactivity > > Which of these is broken depends on your viewpoint. > > > Something that runs fast but is incorrect is still incorrect.? The fact > that the transcript doesn't output until a world step is possible is a > bug.? It forces programs that use the transcript to be rewritten in order > to see transcript output. > > > As a point of comparison for correctness, for the following... > > ? ? Transcript clear. > ? ? [? ?$a asciiValue to: $z asciiValue do: [ :c | > ? [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i > printString , ' ' ] ] forkAt: 40 > ]. > ? ? ] forkAt: 41 > > Squeak 4.5 gives... > $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4 > $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2 > $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7 > $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3 > $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4 > $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5 > $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6 > $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7 > $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8 > $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9 > $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9 > $u9 $z9 $x9 > > Pharo 50041 gives... > $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1 > $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2 > $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3 > $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4 > $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5 > $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6 > $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7 > $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8 > $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9 > $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1 > $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2 > $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3 > $z4 $z5 $z6 $z7 $z8 $z9 > > (start your comparison at $b5) > > So in one axis Pharo has improved Transcript, but we didn't notice the > significance of the use case we lost. > > cheers -ben > > > Please take a good look at Cuis' Transcript and consider using it. > > By default, the display is updated immediately, but without calling Morphic, it can even work with no UI framework at all. It does updates faster than Squeak or Visualworks: > > ? ? ? ? Time millisecondsToRun: [ 1000 timesRepeat:? [ Transcript show: 'x' ] ]. 763. > > But if you want minimum overhead without immediate feedback: > > ? ? ? ? Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 timesRepeat:? [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1. > ? ? ? ? "As fast as Pharo" > > It is also thread safe, and for Ben's example: > > Transcript clear. > [ > ? ? ? ? $a asciiValue to: $z asciiValue do: [ :c | > ? ? ? ? ? ? ? ? [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40 > ? ? ? ? ]. > ] forkAt: 41 > > it gives the same result as Pharo. > > The fact that the updates are not bound to Morphic also means that it is possible to do #show: deep in Morphic logic, without causing infinite loops or recursions, and get immediate feedback. It has > proved to be a useful aid in debugging Morphic code. > > Cheers, > Juan Vuletich > > > > > > -- > best,Eliot > > From florin.mateoc at gmail.com Sat May 9 23:20:32 2015 From: florin.mateoc at gmail.com (Florin Mateoc) Date: Sat May 9 23:20:29 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: References: Message-ID: <554E9640.6010706@gmail.com> On 5/9/2015 7:06 PM, Levente Uzonyi wrote: > The main performance hog is the full redraw of the whole morph for every single #endEntry send. The morph re-renders > all visible lines (see NewParagraph >> #displayOn:using:at:). > If the visible lines' were cached on a form (probably one form per line), and only the newly added text were drawn > during the update, then I think the performance would be similar to Cuis's implementation's, but without restrictions > (text not selectable/editable). > > Levente Transcript writing is slow in VisualWorks and VisualAge as well and neither uses Morphic. My usual workaround is to cover Transcript with another window to avoid the redraws while the heavy activity is happening. I suppose this would work in Morphic as well. This seemed good/simple enough that I never cared to "fix" it. Florin From leves at elte.hu Sat May 9 23:42:39 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sat May 9 23:42:44 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: <554E9640.6010706@gmail.com> References: <554E9640.6010706@gmail.com> Message-ID: On Sat, 9 May 2015, Florin Mateoc wrote: > On 5/9/2015 7:06 PM, Levente Uzonyi wrote: >> The main performance hog is the full redraw of the whole morph for every single #endEntry send. The morph re-renders >> all visible lines (see NewParagraph >> #displayOn:using:at:). >> If the visible lines' were cached on a form (probably one form per line), and only the newly added text were drawn >> during the update, then I think the performance would be similar to Cuis's implementation's, but without restrictions >> (text not selectable/editable). >> >> Levente > > Transcript writing is slow in VisualWorks and VisualAge as well and neither uses Morphic. > My usual workaround is to cover Transcript with another window to avoid the redraws while the heavy activity is > happening. I suppose this would work in Morphic as well. > This seemed good/simple enough that I never cared to "fix" it. Yes, it's way faster if the window is not visible. I used to collapse it when I wanted better performance, but that's not always an option. Levente > > Florin > > From eliot.miranda at gmail.com Sun May 10 02:01:20 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun May 10 02:01:25 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: References: Message-ID: Hi Tudor, On Sat, May 9, 2015 at 2:23 PM, Tudor Girba wrote: > Hi Eliot, > > Just a question: Could you describe the situations when you need to have > the Transcript editable? > > I am not trying to provoke you, > my reputation preceeds me ;-) > but to understand use cases. While working on GT I found that it is often > possible to support the same use cases with multiple UI solutions. And > sometimes considering alternatives leads to interesting results. > While I have an over-full transcript that holds progress over time, notes etc, these could be moved to a workspace. What I really use editablity in the transcript for is to cut-down output. For example, if I'm analysing some jitted code it will get printed out in the transcript (without a lot of retooling) and it is very convenient to cut down the often large amount of output to focus on what I'm interested in. Or I might be trying to fix a bug with repeated runs and again collect relevant data (print outs of objects or stack frames from the simulator) for use as reference points in later runs. Or I might collect some warnings from the Slang SMalltalk-to-C translator. In short, there's a lot of different kinds of data going to the transcript and it can be useful to edit it in place instead of having to copy it elsewhere. > Cheers, > Doru > > > > On Sat, May 9, 2015 at 9:32 PM, Eliot Miranda > wrote: > >> Hi Juan, >> >> I see that your new transcript is indeed much faster but is also not >> editable. I wonder if it would be possible to have the best of both worlds >> and arrange that, when active, the transcript is editable. For example, >> selecting the TranscriptWIndow could put it into a mode where the >> transcript's state was imported into a more conventional editable text >> morph, and then when the window was exited, reverted to the standard fast >> output mode. As you can infer I like having an editable transcript. I can >> do without it, because Squeak's slow transcript is indeed a PITA, but I'm >> not sure that speed need preclude editability. >> >> On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) < >> juanlists@jvuletich.org> wrote: >> >>> Hi Folks, >>> >>> (below) >>> >>> >>> Quoting Ben Coman : >>> >>> On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda >>> > >>>> wrote: >>>> >>>> >>>>> >>>>> On Sat, May 9, 2015 at 7:09 AM, Ben Coman wrote: >>>>> >>>>> From my limited experience bug hunting, calling #changed: from a >>>>>> thread >>>>>> other than the UI thread is a source of evil. There are too many >>>>>> assumptions throughout the system that the UI is single threaded. Can >>>>>> anyone advise me that is not a proper belief? >>>>>> >>>>>> Then that implies that a Transcript implementation where #nextPut: >>>>>> direct >>>>>> calls #changed: >>>>>> is not appropriate for use with multi-threaded applications. In >>>>>> Pharo, >>>>>> #changed: is only called from #stepGlobal, which is called from >>>>>> doOneCycle:. (This came about as a last minute bug fix before Pharo 3 >>>>>> release and maybe could use some cleanup. >>>>>> >>>>>> Separating the UI from Transcript into its own viewer might be a good >>>>>> idea, but actually it would not solve Stef's case since his code would >>>>>> still be running in the UI thread -- unless the viewer ran in another >>>>>> thread, which would have its own complexities. >>>>>> >>>>>> I think the point about efficiency is significant. The following >>>>>> example... >>>>>> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: >>>>>> 'x' >>>>>> ] ] >>>>>> on Squeak 4.5 --> 12749ms >>>>>> on Pharo 50029 --> 2ms >>>>>> >>>>>> This better performance helped me a lot trying to understand the high >>>>>> priority timerEventLoop being able to indiscriminately scatter >>>>>> Transcript >>>>>> tracing through that code. I believe its also probably beneficial for >>>>>> working with externally triggered semaphores and timing sensitive race >>>>>> conditions. >>>>>> >>>>>> So we have two mutually exclusive cases: >>>>>> * better interactivity, poorer system performance >>>>>> * faster system performance, worse interactivity >>>>>> >>>>>> Which of these is broken depends on your viewpoint. >>>>>> >>>>>> >>>>> Something that runs fast but is incorrect is still incorrect. The fact >>>>> that the transcript doesn't output until a world step is possible is a >>>>> bug. It forces programs that use the transcript to be rewritten in >>>>> order >>>>> to see transcript output. >>>>> >>>>> >>>> As a point of comparison for correctness, for the following... >>>> >>>> Transcript clear. >>>> [ $a asciiValue to: $z asciiValue do: [ :c | >>>> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i >>>> printString , ' ' ] ] forkAt: 40 >>>> ]. >>>> ] forkAt: 41 >>>> >>>> Squeak 4.5 gives... >>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 >>>> $c4 >>>> $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 >>>> $h2 >>>> $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 >>>> $b7 >>>> $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 >>>> $u3 >>>> $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 >>>> $o4 >>>> $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 >>>> $m5 >>>> $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 >>>> $k6 >>>> $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 >>>> $l7 >>>> $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 >>>> $h8 >>>> $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 >>>> $f9 >>>> $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 >>>> $u9 >>>> $u9 $z9 $x9 >>>> >>>> Pharo 50041 gives... >>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 >>>> $c1 >>>> $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 >>>> $e2 >>>> $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 >>>> $g3 >>>> $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 >>>> $i4 >>>> $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 >>>> $k5 >>>> $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 >>>> $m6 >>>> $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 >>>> $o7 >>>> $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 >>>> $q8 >>>> $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 >>>> $s9 >>>> $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 >>>> $v1 >>>> $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 >>>> $x2 >>>> $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 >>>> $z3 >>>> $z4 $z5 $z6 $z7 $z8 $z9 >>>> >>>> (start your comparison at $b5) >>>> >>>> So in one axis Pharo has improved Transcript, but we didn't notice the >>>> significance of the use case we lost. >>>> >>>> cheers -ben >>>> >>> >>> Please take a good look at Cuis' Transcript and consider using it. >>> >>> By default, the display is updated immediately, but without calling >>> Morphic, it can even work with no UI framework at all. It does updates >>> faster than Squeak or Visualworks: >>> >>> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: >>> 'x' ] ]. 763. >>> >>> But if you want minimum overhead without immediate feedback: >>> >>> Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 >>> timesRepeat: [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1. >>> "As fast as Pharo" >>> >>> It is also thread safe, and for Ben's example: >>> >>> Transcript clear. >>> [ >>> $a asciiValue to: $z asciiValue do: [ :c | >>> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter >>> printString , i printString , ' ' ] ] forkAt: 40 >>> ]. >>> ] forkAt: 41 >>> >>> it gives the same result as Pharo. >>> >>> The fact that the updates are not bound to Morphic also means that it is >>> possible to do #show: deep in Morphic logic, without causing infinite loops >>> or recursions, and get immediate feedback. It has proved to be a useful aid >>> in debugging Morphic code. >>> >>> Cheers, >>> Juan Vuletich >>> >>> >>> >> >> >> -- >> best, >> Eliot >> > > > > -- > www.tudorgirba.com > > "Every thing has its own flow" > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150509/6891322d/attachment.htm From karlramberg at gmail.com Sun May 10 06:41:54 2015 From: karlramberg at gmail.com (karl ramberg) Date: Sun May 10 06:41:57 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: References: Message-ID: If you disable preference 'Force Transcrip updates to screen' you will get much higher performance. Redrawing is then minimal Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: 'x'] ] 694 Karl On Sun, May 10, 2015 at 4:01 AM, Eliot Miranda wrote: > Hi Tudor, > > On Sat, May 9, 2015 at 2:23 PM, Tudor Girba wrote: > >> Hi Eliot, >> >> Just a question: Could you describe the situations when you need to have >> the Transcript editable? >> >> I am not trying to provoke you, >> > > my reputation preceeds me ;-) > > > >> but to understand use cases. While working on GT I found that it is often >> possible to support the same use cases with multiple UI solutions. And >> sometimes considering alternatives leads to interesting results. >> > > While I have an over-full transcript that holds progress over time, notes > etc, these could be moved to a workspace. What I really use editablity in > the transcript for is to cut-down output. For example, if I'm analysing > some jitted code it will get printed out in the transcript (without a lot > of retooling) and it is very convenient to cut down the often large amount > of output to focus on what I'm interested in. Or I might be trying to fix > a bug with repeated runs and again collect relevant data (print outs of > objects or stack frames from the simulator) for use as reference points in > later runs. Or I might collect some warnings from the Slang SMalltalk-to-C > translator. > > In short, there's a lot of different kinds of data going to the transcript > and it can be useful to edit it in place instead of having to copy it > elsewhere. > > >> Cheers, >> Doru >> >> >> >> On Sat, May 9, 2015 at 9:32 PM, Eliot Miranda >> wrote: >> >>> Hi Juan, >>> >>> I see that your new transcript is indeed much faster but is also not >>> editable. I wonder if it would be possible to have the best of both worlds >>> and arrange that, when active, the transcript is editable. For example, >>> selecting the TranscriptWIndow could put it into a mode where the >>> transcript's state was imported into a more conventional editable text >>> morph, and then when the window was exited, reverted to the standard fast >>> output mode. As you can infer I like having an editable transcript. I can >>> do without it, because Squeak's slow transcript is indeed a PITA, but I'm >>> not sure that speed need preclude editability. >>> >>> On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) < >>> juanlists@jvuletich.org> wrote: >>> >>>> Hi Folks, >>>> >>>> (below) >>>> >>>> >>>> Quoting Ben Coman : >>>> >>>> On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda < >>>>> eliot.miranda@gmail.com> >>>>> wrote: >>>>> >>>>> >>>>>> >>>>>> On Sat, May 9, 2015 at 7:09 AM, Ben Coman >>>>>> wrote: >>>>>> >>>>>> >From my limited experience bug hunting, calling #changed: from a >>>>>>> thread >>>>>>> other than the UI thread is a source of evil. There are too many >>>>>>> assumptions throughout the system that the UI is single threaded. >>>>>>> Can >>>>>>> anyone advise me that is not a proper belief? >>>>>>> >>>>>>> Then that implies that a Transcript implementation where #nextPut: >>>>>>> direct >>>>>>> calls #changed: >>>>>>> is not appropriate for use with multi-threaded applications. In >>>>>>> Pharo, >>>>>>> #changed: is only called from #stepGlobal, which is called from >>>>>>> doOneCycle:. (This came about as a last minute bug fix before Pharo >>>>>>> 3 >>>>>>> release and maybe could use some cleanup. >>>>>>> >>>>>>> Separating the UI from Transcript into its own viewer might be a good >>>>>>> idea, but actually it would not solve Stef's case since his code >>>>>>> would >>>>>>> still be running in the UI thread -- unless the viewer ran in another >>>>>>> thread, which would have its own complexities. >>>>>>> >>>>>>> I think the point about efficiency is significant. The following >>>>>>> example... >>>>>>> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: >>>>>>> 'x' >>>>>>> ] ] >>>>>>> on Squeak 4.5 --> 12749ms >>>>>>> on Pharo 50029 --> 2ms >>>>>>> >>>>>>> This better performance helped me a lot trying to understand the high >>>>>>> priority timerEventLoop being able to indiscriminately scatter >>>>>>> Transcript >>>>>>> tracing through that code. I believe its also probably beneficial >>>>>>> for >>>>>>> working with externally triggered semaphores and timing sensitive >>>>>>> race >>>>>>> conditions. >>>>>>> >>>>>>> So we have two mutually exclusive cases: >>>>>>> * better interactivity, poorer system performance >>>>>>> * faster system performance, worse interactivity >>>>>>> >>>>>>> Which of these is broken depends on your viewpoint. >>>>>>> >>>>>>> >>>>>> Something that runs fast but is incorrect is still incorrect. The >>>>>> fact >>>>>> that the transcript doesn't output until a world step is possible is a >>>>>> bug. It forces programs that use the transcript to be rewritten in >>>>>> order >>>>>> to see transcript output. >>>>>> >>>>>> >>>>> As a point of comparison for correctness, for the following... >>>>> >>>>> Transcript clear. >>>>> [ $a asciiValue to: $z asciiValue do: [ :c | >>>>> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i >>>>> printString , ' ' ] ] forkAt: 40 >>>>> ]. >>>>> ] forkAt: 41 >>>>> >>>>> Squeak 4.5 gives... >>>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 >>>>> $c3 $c4 >>>>> $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 >>>>> $h2 $h2 >>>>> $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 >>>>> $z2 $b7 >>>>> $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 >>>>> $t3 $u3 >>>>> $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 >>>>> $q4 $o4 >>>>> $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 >>>>> $l5 $m5 >>>>> $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 >>>>> $g6 $k6 >>>>> $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 >>>>> $i7 $l7 >>>>> $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 >>>>> $e8 $h8 >>>>> $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 >>>>> $z8 $f9 >>>>> $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 >>>>> $v9 $u9 >>>>> $u9 $z9 $x9 >>>>> >>>>> Pharo 50041 gives... >>>>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 >>>>> $b9 $c1 >>>>> $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 >>>>> $e1 $e2 >>>>> $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 >>>>> $g2 $g3 >>>>> $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 >>>>> $i3 $i4 >>>>> $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 >>>>> $k4 $k5 >>>>> $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 >>>>> $m5 $m6 >>>>> $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 >>>>> $o6 $o7 >>>>> $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 >>>>> $q7 $q8 >>>>> $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 >>>>> $s8 $s9 >>>>> $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 >>>>> $u9 $v1 >>>>> $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 >>>>> $x1 $x2 >>>>> $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 >>>>> $z2 $z3 >>>>> $z4 $z5 $z6 $z7 $z8 $z9 >>>>> >>>>> (start your comparison at $b5) >>>>> >>>>> So in one axis Pharo has improved Transcript, but we didn't notice the >>>>> significance of the use case we lost. >>>>> >>>>> cheers -ben >>>>> >>>> >>>> Please take a good look at Cuis' Transcript and consider using it. >>>> >>>> By default, the display is updated immediately, but without calling >>>> Morphic, it can even work with no UI framework at all. It does updates >>>> faster than Squeak or Visualworks: >>>> >>>> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: >>>> 'x' ] ]. 763. >>>> >>>> But if you want minimum overhead without immediate feedback: >>>> >>>> Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 >>>> timesRepeat: [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1. >>>> "As fast as Pharo" >>>> >>>> It is also thread safe, and for Ben's example: >>>> >>>> Transcript clear. >>>> [ >>>> $a asciiValue to: $z asciiValue do: [ :c | >>>> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter >>>> printString , i printString , ' ' ] ] forkAt: 40 >>>> ]. >>>> ] forkAt: 41 >>>> >>>> it gives the same result as Pharo. >>>> >>>> The fact that the updates are not bound to Morphic also means that it >>>> is possible to do #show: deep in Morphic logic, without causing infinite >>>> loops or recursions, and get immediate feedback. It has proved to be a >>>> useful aid in debugging Morphic code. >>>> >>>> Cheers, >>>> Juan Vuletich >>>> >>>> >>>> >>> >>> >>> -- >>> best, >>> Eliot >>> >> >> >> >> -- >> www.tudorgirba.com >> >> "Every thing has its own flow" >> > > > > -- > best, > Eliot > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150510/db6ffe05/attachment.htm From commits at source.squeak.org Sun May 10 10:18:38 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 10:18:39 2015 Subject: [squeak-dev] The Trunk: SUnitGUI-mt.62.mcz Message-ID: Marcel Taeumel uploaded a new version of SUnitGUI to project The Trunk: http://source.squeak.org/trunk/SUnitGUI-mt.62.mcz ==================== Summary ==================== Name: SUnitGUI-mt.62 Author: mt Time: 10 May 2015, 12:18:33.708 pm UUID: 23278a70-3219-2542-bdb0-1e42b35989a6 Ancestors: SUnitGUI-topa.61 Upper spacing of button bar in test runner fixed by removing some magic numbers. =============== Diff against SUnitGUI-topa.61 =============== Item was changed: ----- Method: TestRunner>>categoriesFrame (in category 'building') ----- categoriesFrame ^LayoutFrame new leftFraction: 0 offset: 0; topFraction: 0 offset: 0; rightFraction: 0.25 offset: 0; + bottomFraction: 1 offset: self buttonHeight negated! - bottomFraction: 1 offset: self buttonHeight negated + 4! Item was changed: ----- Method: TestRunner>>classesFrame (in category 'building') ----- classesFrame ^LayoutFrame new leftFraction: 0.25 offset: 0; topFraction: 0 offset: 0; rightFraction: 0.5 offset: 0; + bottomFraction: 1 offset: self buttonHeight negated! - bottomFraction: 1 offset: self buttonHeight negated + 4! Item was changed: ----- Method: TestRunner>>errorListFrame (in category 'building') ----- errorListFrame ^LayoutFrame new leftFraction: 0.5 offset: 0; topFraction: 0.5 offset: 0; rightFraction: 1 offset: 0; + bottomFraction: 1 offset: self buttonHeight negated! - bottomFraction: 1 offset: self buttonHeight negated + 4! From leves at elte.hu Sun May 10 10:45:33 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sun May 10 10:45:39 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: References: Message-ID: On Sun, 10 May 2015, karl ramberg wrote: > If you disable preference 'Force Transcrip updates to screen' you will get much higher performance.Redrawing is then minimal > Time millisecondsToRun: [ 1000 timesRepeat: ?[ Transcript show: 'x'] ] 694 Right, but then it won't update the contents of the morph, while your code is running in the UI process. So you have to fork your process, just like in Pharo. Levente > > Karl > > On Sun, May 10, 2015 at 4:01 AM, Eliot Miranda wrote: > Hi Tudor, > > On Sat, May 9, 2015 at 2:23 PM, Tudor Girba wrote: > Hi Eliot, > Just a question: Could you describe the situations when you need to have the Transcript editable? > > I am not trying to provoke you, > > > my reputation preceeds me ;-) > > ? > but to understand use cases. While working on GT I found that it is often possible to support the same use cases with multiple UI solutions. And sometimes considering alternatives leads to > interesting results. > > > While I have an over-full transcript that holds progress over time, notes etc, these could be moved to a workspace.? What I really use editablity in the transcript for is to cut-down output.? For > example, if I'm analysing some jitted code it will get printed out in the transcript (without a lot of retooling) and it is very convenient to cut down the often large amount of output to focus on what > I'm interested in.? Or I might be trying to fix a bug with repeated runs and again collect relevant data (print outs of objects or stack frames from the simulator) for use as reference points in later > runs.? Or I might collect some warnings from the Slang SMalltalk-to-C translator. > > In short, there's a lot of different kinds of data going to the transcript and it can be useful to edit it in place instead of having to copy it elsewhere. > > > Cheers, > Doru > > > > On Sat, May 9, 2015 at 9:32 PM, Eliot Miranda wrote: > Hi Juan, > ? ? I see that your new transcript is indeed much faster but is also not editable.? I wonder if it would be possible to have the best of both worlds and arrange that, when active, the > transcript is editable.? For example, selecting the TranscriptWIndow could put it into a mode where the transcript's state was imported into a more conventional editable text morph, and then > when the window was exited, reverted to the standard fast output mode.? As you can infer I like having an editable transcript.? I can do without it, because Squeak's slow transcript is > indeed a PITA, but I'm not sure that speed need preclude editability. > > On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) wrote: > Hi Folks, > > (below) > > Quoting Ben Coman : > > On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda > wrote: > > > > On Sat, May 9, 2015 at 7:09 AM, Ben Coman wrote: > > >From my limited experience bug hunting, calling #changed: from a thread > other than the UI thread is a source of evil.? There are too many > assumptions throughout the system that the UI is single threaded.? Can > anyone advise me that is not a proper belief? > > Then that implies that a Transcript implementation where #nextPut: direct > calls #changed: > is not appropriate for use with multi-threaded applications.? In Pharo, > #changed: is only called from #stepGlobal, which is called from > doOneCycle:.? (This came about as a last minute bug fix before Pharo 3 > release and maybe could use some cleanup. > > Separating the UI from Transcript into its own viewer might be a good > idea, but actually it would not solve Stef's case since his code would > still be running in the UI thread -- unless the viewer ran in another > thread, which would have its own complexities. > > I think the point about efficiency is significant. The following > example... > ? ? ?Time millisecondsToRun: [ 1000 timesRepeat:? [ Transcript show: 'x' > ] ] > on Squeak 4.5 --> 12749ms > on Pharo 50029 --> 2ms > > This better performance helped me a lot trying to understand the high > priority timerEventLoop being able to indiscriminately scatter Transcript > tracing through that code.? I believe its also probably beneficial for > working with externally triggered semaphores and timing sensitive race > conditions. > > So we have two mutually exclusive cases: > * better interactivity, poorer system performance > * faster system performance, worse interactivity > > Which of these is broken depends on your viewpoint. > > > Something that runs fast but is incorrect is still incorrect.? The fact > that the transcript doesn't output until a world step is possible is a > bug.? It forces programs that use the transcript to be rewritten in order > to see transcript output. > > > As a point of comparison for correctness, for the following... > > ? ? Transcript clear. > ? ? [? ?$a asciiValue to: $z asciiValue do: [ :c | > ? [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i > printString , ' ' ] ] forkAt: 40 > ]. > ? ? ] forkAt: 41 > > Squeak 4.5 gives... > $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 $c4 > $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 $h2 > $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 $b7 > $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 $u3 > $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 $o4 > $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 $m5 > $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 $k6 > $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 $l7 > $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 $h8 > $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 $f9 > $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 $u9 > $u9 $z9 $x9 > > Pharo 50041 gives... > $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 $c1 > $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 $e2 > $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 $g3 > $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 $i4 > $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 $k5 > $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 $m6 > $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 $o7 > $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 $q8 > $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 $s9 > $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 $v1 > $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 $x2 > $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 $z3 > $z4 $z5 $z6 $z7 $z8 $z9 > > (start your comparison at $b5) > > So in one axis Pharo has improved Transcript, but we didn't notice the > significance of the use case we lost. > > cheers -ben > > > Please take a good look at Cuis' Transcript and consider using it. > > By default, the display is updated immediately, but without calling Morphic, it can even work with no UI framework at all. It does updates faster than Squeak or Visualworks: > > ? ? ? ? Time millisecondsToRun: [ 1000 timesRepeat:? [ Transcript show: 'x' ] ]. 763. > > But if you want minimum overhead without immediate feedback: > > ? ? ? ? Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 timesRepeat:? [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1. > ? ? ? ? "As fast as Pharo" > > It is also thread safe, and for Ben's example: > > Transcript clear. > [ > ? ? ? ? $a asciiValue to: $z asciiValue do: [ :c | > ? ? ? ? ? ? ? ? [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i printString , ' ' ] ] forkAt: 40 > ? ? ? ? ]. > ] forkAt: 41 > > it gives the same result as Pharo. > > The fact that the updates are not bound to Morphic also means that it is possible to do #show: deep in Morphic logic, without causing infinite loops or recursions, and get immediate > feedback. It has proved to be a useful aid in debugging Morphic code. > > Cheers, > Juan Vuletich > > > > > > -- > best,Eliot > > > > > -- > www.tudorgirba.com > > "Every thing has its own flow" > > > > > -- > best,Eliot > > > > > > From commits at source.squeak.org Sun May 10 11:54:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 11:54:42 2015 Subject: [squeak-dev] The Trunk: HelpSystem-Core-mt.74.mcz Message-ID: Marcel Taeumel uploaded a new version of HelpSystem-Core to project The Trunk: http://source.squeak.org/trunk/HelpSystem-Core-mt.74.mcz ==================== Summary ==================== Name: HelpSystem-Core-mt.74 Author: mt Time: 10 May 2015, 1:54:34.265 pm UUID: 6c85fc29-286f-144f-987a-c450aa4201dd Ancestors: HelpSystem-Core-mt.73 Added support for ignoring class-based help topics. =============== Diff against HelpSystem-Core-mt.73 =============== Item was changed: ----- Method: ClassBasedHelpTopic>>updateSubtopics (in category 'updating') ----- updateSubtopics | pages | pages := (self helpClass pages collect: [:pageSelectorOrClassName | (Smalltalk hasClassNamed: pageSelectorOrClassName asString) ifTrue: [Smalltalk classNamed: pageSelectorOrClassName asString] ifFalse: [pageSelectorOrClassName]]) asOrderedCollection. + self helpClass subclasses + select: [:cls | cls ignore not] + thenDo: [:cls | pages addIfNotPresent: cls]. - self helpClass subclasses do: [:cls | - pages addIfNotPresent: cls]. ^ subtopics := pages withIndexCollect: [:pageSelectorOrClass :priority | pageSelectorOrClass isBehavior ifFalse: [(self helpClass perform: pageSelectorOrClass) priority: priority - pages size; yourself] ifTrue: [pageSelectorOrClass asHelpTopic]]! Item was added: + ----- Method: CustomHelp class>>ignore (in category 'accessing') ----- + ignore + + ^ false! From commits at source.squeak.org Sun May 10 11:55:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 11:55:57 2015 Subject: [squeak-dev] The Trunk: Help-Squeak-SWiki-mt.2.mcz Message-ID: Marcel Taeumel uploaded a new version of Help-Squeak-SWiki to project The Trunk: http://source.squeak.org/trunk/Help-Squeak-SWiki-mt.2.mcz ==================== Summary ==================== Name: Help-Squeak-SWiki-mt.2 Author: mt Time: 10 May 2015, 1:55:51.449 pm UUID: 76848f48-14f6-c540-860a-a42fd4259c1b Ancestors: Help-Squeak-SWiki-mt.1 Only support opening SWiki in HelpBrowser directly. Ignore it if embedded in other help structures. SWiki help integration is still experimental and should not confuse other users. =============== Diff against Help-Squeak-SWiki-mt.1 =============== Item was changed: CustomHelp subclass: #SWikiHelp instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Help-Squeak-SWiki'! + + !SWikiHelp commentStamp: 'mt 5/10/2015 13:52' prior: 0! + HelpBrowser openOn: SWikiHelp.! Item was added: + ----- Method: SWikiHelp class>>ignore (in category 'accessing') ----- + ignore + "Experimental." + ^ true! From commits at source.squeak.org Sun May 10 11:57:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 11:57:09 2015 Subject: [squeak-dev] The Trunk: GetText-mt.37.mcz Message-ID: Marcel Taeumel uploaded a new version of GetText to project The Trunk: http://source.squeak.org/trunk/GetText-mt.37.mcz ==================== Summary ==================== Name: GetText-mt.37 Author: mt Time: 10 May 2015, 1:57:01.667 pm UUID: 0033c111-0112-dd4f-95ac-0a56cc7a0f68 Ancestors: GetText-nice.36 Skip registering LanguageEditor in world menu for now because it is not functional at the moment. =============== Diff against GetText-nice.36 =============== Item was changed: ----- Method: LanguageEditor class>>initialize (in category 'initialize-release') ----- initialize "initialize the receiver" + "(TheWorldMenu respondsTo: #registerOpenCommand:) + ifTrue: [ - (TheWorldMenu respondsTo: #registerOpenCommand:) - ifTrue: ["" TheWorldMenu registerOpenCommand: {'Language Editor' translated. {self. #openOnDefault}}. + TheWorldMenu registerOpenCommand: {'Language Editor for...' translated. {self. #open}}]"! - TheWorldMenu registerOpenCommand: {'Language Editor for...' translated. {self. #open}}]! From commits at source.squeak.org Sun May 10 12:01:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 12:01:47 2015 Subject: [squeak-dev] The Trunk: Universes-mt.48.mcz Message-ID: Marcel Taeumel uploaded a new version of Universes to project The Trunk: http://source.squeak.org/trunk/Universes-mt.48.mcz ==================== Summary ==================== Name: Universes-mt.48 Author: mt Time: 10 May 2015, 2:01:40.643 pm UUID: 7bdf9c4b-71d8-9449-9786-9a21743e6866 Ancestors: Universes-kfr.47 Skip registering Universe tools in the world menu because they are not functional at the moment. =============== Diff against Universes-kfr.47 =============== Item was changed: - SystemOrganization addCategory: #'Universes-Interface'! - SystemOrganization addCategory: #'Universes-Editor'! SystemOrganization addCategory: #'Universes-Browser'! - SystemOrganization addCategory: #'Universes-Policy'! - SystemOrganization addCategory: #'Universes-Model'! - SystemOrganization addCategory: #'Universes-Tests'! - SystemOrganization addCategory: #'Universes-Server'! SystemOrganization addCategory: #'Universes-Client'! + SystemOrganization addCategory: #'Universes-Editor'! SystemOrganization addCategory: #'Universes-Installers'! + SystemOrganization addCategory: #'Universes-Interface'! SystemOrganization addCategory: #'Universes-Messages'! + SystemOrganization addCategory: #'Universes-Model'! + SystemOrganization addCategory: #'Universes-Policy'! SystemOrganization addCategory: #'Universes-Serialization'! + SystemOrganization addCategory: #'Universes-Server'! + SystemOrganization addCategory: #'Universes-Tests'! Item was changed: ----- Method: UUniverseBrowser class>>initialize (in category 'class initialization') ----- initialize + #('Package Browser (basic)' 'Universe Browser' 'Package Universe Browser') do: [:oldName | - #('Package Browser (basic)' 'Universe Browser') do: [:oldName | TheWorldMenu unregisterOpenCommand: oldName ]. + "TheWorldMenu registerOpenCommand: {'Universe Browser (basic)'. {self. #open}}. + Preferences setWindowColorFor: self name to: (Color r: 0.194 g: 0.645 b: 1.0)."! - TheWorldMenu registerOpenCommand: {'Universe Browser (basic)'. {self. #open}}. - Preferences setWindowColorFor: self name to: (Color r: 0.194 g: 0.645 b: 1.0).! Item was changed: ----- Method: UUniverseBrowser class>>unload (in category 'class initialization') ----- unload + + #('Package Browser (basic)' 'Universe Browser' 'Package Universe Browser') do: [:oldName | + TheWorldMenu unregisterOpenCommand: oldName ].! - TheWorldMenu unregisterOpenCommand: 'Universe Browser (basic)'! Item was changed: ----- Method: UUniverseEditor class>>initialize (in category 'class initialization') ----- initialize - TheWorldMenu unregisterOpenCommand: 'Package Universe Editor'. + #('Universe Editor' 'Package Universe Editor') do: [:oldName | + TheWorldMenu unregisterOpenCommand: oldName]. + + "TheWorldMenu registerOpenCommand: {'Universe Editor'. {self. #open}}. + Preferences setWindowColorFor: self name to: (Color r: 0.194 g: 0.645 b: 1.0)."! - TheWorldMenu registerOpenCommand: {'Universe Editor'. {self. #open}}. - Preferences setWindowColorFor: self name to: (Color r: 0.194 g: 0.645 b: 1.0).! Item was changed: ----- Method: UUniverseEditor class>>unload (in category 'class initialization') ----- unload + + #('Universe Editor' 'Package Universe Editor') do: [:oldName | + TheWorldMenu unregisterOpenCommand: oldName]. + ! - TheWorldMenu unregisterOpenCommand: 'Universe Editor'! From commits at source.squeak.org Sun May 10 12:04:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 12:04:28 2015 Subject: [squeak-dev] The Trunk: Graphics-mt.313.mcz Message-ID: Marcel Taeumel uploaded a new version of Graphics to project The Trunk: http://source.squeak.org/trunk/Graphics-mt.313.mcz ==================== Summary ==================== Name: Graphics-mt.313 Author: mt Time: 10 May 2015, 2:04:07.524 pm UUID: 99af1adc-65b3-5549-8d10-ab452e0c59e5 Ancestors: Graphics-mt.312 Conveniently adjust saturation or brightness of forms. =============== Diff against Graphics-mt.312 =============== Item was added: + ----- Method: Form>>adjustBrightness: (in category 'converting') ----- + adjustBrightness: brightness + + ^ self collectColors: [:color | color adjustSaturation: 0 brightness: brightness]! Item was added: + ----- Method: Form>>adjustSaturation: (in category 'converting') ----- + adjustSaturation: saturation + + ^ self collectColors: [:color | color adjustSaturation: saturation brightness: 0]! From commits at source.squeak.org Sun May 10 12:32:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 12:32:02 2015 Subject: [squeak-dev] The Trunk: Collections-mt.635.mcz Message-ID: Marcel Taeumel uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.635.mcz ==================== Summary ==================== Name: Collections-mt.635 Author: mt Time: 10 May 2015, 2:31:43.749 pm UUID: 5c6d47bf-db22-7a4b-b35e-24626842474b Ancestors: Collections-ul.634 Some debug code removed from html readwriter.. =============== Diff against Collections-ul.634 =============== Item was changed: ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- mapATag: aTag | result startIndex stopIndex attribute | result := OrderedCollection new. - - Transcript showln: aTag. "
" attribute := 'href'. startIndex := aTag findString: attribute. startIndex > 0 ifTrue: [ startIndex := aTag findString: '=' startingAt: startIndex+attribute size. stopIndex := aTag findString: ' ' startingAt: startIndex+1. stopIndex = 0 ifTrue: [ stopIndex := aTag findString: '>' startingAt: startIndex+1]. (aTag at: startIndex + 1) = $" ifTrue: [startIndex := startIndex + 1]. (aTag at: stopIndex - 1) = $" ifTrue: [stopIndex := stopIndex - 1]. result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. ^ result! From commits at source.squeak.org Sun May 10 12:53:25 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 12:53:27 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.975.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.975.mcz ==================== Summary ==================== Name: Morphic-mt.975 Author: mt Time: 10 May 2015, 2:52:49.059 pm UUID: 0fc30e99-40c1-6042-9eba-14903faaf027 Ancestors: Morphic-mt.974 Reduced/updated icon usage in menus to make those other icons more effective. Postscript unloads menu entries for universe tools and language editor tools because those are not functional the moment. =============== Diff against Morphic-mt.974 =============== Item was added: + ----- Method: MenuIcons class>>fugueBroomIcon (in category 'private - icons') ----- + fugueBroomIcon + + ^ Icons + at: #broom + ifAbsentPut:[ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self fugueBroomIconContents readStream) ].! Item was added: + ----- Method: MenuIcons class>>fugueBroomIconContents (in category 'private - icons') ----- + fugueBroomIconContents + "Fugue Icons + (C) 2013 Yusuke Kamiyamane. All rights reserved. + + These icons are licensed under a Creative Commons + Attribution 3.0 License. + " + + ^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i + ZSBJbWFnZVJlYWR5ccllPAAAAoNJREFUeNqkU11Ik1EYfo6bm7WZW2r+MDNTZ9ZQcbYws0iN + piZEBF4UXWgXCXURXQQiBTYhgi4qRo0y+gEpNImauKVkhkzDNrxoCjrNZSSapnNLv+n2nc5H + GmFJgQcezuGc93nPc877vIRSivUMYqwkEFIIeQQQsnzA5rP1FEe0BKXZP894Bm6AQiKGPsjD + sLSEmpD/uCSX8e4JYOv9LJF+noNhb/ExrW8BBvE/yClmO824YbpaKUgwG6sjvy8gQVdwQNv4 + qNkeCK6tQMHiz7H5kMs1fKe1Rw7/xARKTl8+Gq4hX5496bR/nkINz8MiKAhliGCIYohjRF2Y + LCJnW2ZelrM8I6mlxYzCQj1arX4cTBzC4ZMXyhYD11soD074E3KrglwJkyl3S2WbZBvCI8Oj + E1JjlDGqqCXvojjg4bB5ZwKaO0NRUFAKq/U5CpOGIRKJYG2638AuOxHCZLT5PDP+NF3Jvvhk + bSY3y8eOdA+IvV9nsFGlxLf+MZRle2E2NyI/vxQvnXGYc88hEABhgEifSdw2O521dfSmyyji + ZRFyxKSqIGK1Gu8bgTI5FgEfh3TFPBra+6BW70H5+dqGvBTUs2d8XKmCJVtDFqanHRd35GqK + hxz9EFMRtmakwDc1C8oFoUjcglO7PNCdKW9i8beZ/C7BMr+qwDY6+/rpTeO1h3ZFlAJJOWqM + D36CZ3IG0mg5Jj+48fjp3bdV+dTEwrtWeKt9YEnbTvy21y+q1ercIp59UHJWGsYcQ7B0tHUz + 99WFSdH+O+EPIzElHa5RKnWN2pQVVce1gz1OvHn3vpcPolYiwavV8Ws50SKVgD4wNdUt98il + EALLX5tp3d243gQ/BBgABJ4L2+7frOgAAAAASUVORK5CYII='! Item was added: + ----- Method: MenuIcons class>>fugueDocumentClockIcon (in category 'private - icons') ----- + fugueDocumentClockIcon + + ^ Icons + at: #documentClock + ifAbsentPut:[ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self fugueDocumentClockIconContents readStream) ].! Item was added: + ----- Method: MenuIcons class>>fugueDocumentClockIconContents (in category 'private - icons') ----- + fugueDocumentClockIconContents + "Fugue Icons + (C) 2013 Yusuke Kamiyamane. All rights reserved. + + These icons are licensed under a Creative Commons + Attribution 3.0 License. + " + + ^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i + ZSBJbWFnZVJlYWR5ccllPAAAAhNJREFUeNqMU11LG1EQPbvZfEgaSKKBtFX71BcFjT8hCb4I + Pjb1qc/9F4og9AcU6rPgk9KCb0Uw0D9gCsWAaSJBoSSp+Wg2rbp3d3vuDZtuWS0dmL3DvTNn + 5szMaq7rQkppa2udx2P8W04cx/nq2Dbe7+yoC8N74cOTvc3N3Ts+WlIdBzbBvQSVSgV7x8ev + aWrUmhenTwBsW3NkkGUpvbu5wa/RCKZpYjgcqvNwe3uXfkW6Pw8A2ASQ0Dq/4VAIsXAYEcOA + oevQeNftdvF2fx+FhYV3X05PX3pxhq8CXQbrCgYKZCJCoFAoKDqJRAIfK5VeAEDICnwA94EI + UvR8AwC2EBMKI3Kv1+vo9/sqa5xZs3NzMCIRRUf6BnsghKLwk8Gf2XGX/KdiMSytrMCIRlE7 + O4O4vUVoDKAHAAQv1XzOzxFlxqlkEh8ODtBh9+PpNBKpFK4uLhQt8QCA6sH3TgdxBs8yqNVq + 4dnMDJ4yODk9jd71NcKcivBR+NMDy1IVWNwBnU5S2+02Xm1sIJvNYnVtTS7bmAJ9g1OQFPiY + YrYfrMLNZHB4dDQeMRtZrVZhDgZqDR+mwDOXy+Fbs4lGrSabpVTazUYDS8vLakr3UuDaKjvN + ClaLRZTLZXyiSpmdn0c+n1dvms/3L4BBrxf17AzLf1EqqR2Qv5J3Sioae+P3nQCMTPPy0eLi + G/yHEOTSs38LMADvCBAJ/QIAlQAAAABJRU5ErkJggg=='! Item was added: + ----- Method: MenuIcons class>>fugueUserSilhouetteQuestionIcon (in category 'private - icons') ----- + fugueUserSilhouetteQuestionIcon + + ^ Icons + at: #userSilhouetteQuestion + ifAbsentPut:[ Form fromBinaryStream: (Base64MimeConverter mimeDecodeToBytes: self fugueUserSilhouetteQuestionIconContents readStream) ].! Item was added: + ----- Method: MenuIcons class>>fugueUserSilhouetteQuestionIconContents (in category 'private - icons') ----- + fugueUserSilhouetteQuestionIconContents + "Fugue Icons + (C) 2013 Yusuke Kamiyamane. All rights reserved. + + These icons are licensed under a Creative Commons + Attribution 3.0 License. + " + + ^ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9i + ZSBJbWFnZVJlYWR5ccllPAAAAgBJREFUeNqkk7+LGlEQx2f9rXiLvwhYHYQENaRJ4RJFsFMQ + bLQOBCRFSBGLtJciYJc21wRsUqS7v0IRlSNFjjt/d6IJaKEXFV1v853H3rHZmKTIwIfdN+87 + s/PmzUqappEkSWSyJ+AFeKSvL8FH8MUoErEHEqQ8Hs/7eDz+MBwOy+yYTCaLdrvdX61Wb7Cs + GRNY6Hd7qShKLBQKBfb7vU1VVVswGAwgYYz3zGJzgjiI+ny+o+12S8xutxP4/f4j3tM1v57D + YF/x9etsNqvN5/M7arWalslkNN5jjTHWZqrgHNy3WCxUqVREb5LJJKVSKYpEItRsNiVd88cj + PG+1Wg0EqqPRiIbDIS0WC5pOpzSbzVTeY83fErCd9nq9Gb9Eo1FKp9NUrVb56+w7/VcT2c4G + g8G13W6nUqlEnU6HxuMxV8PnPzOLbQfWr4CVF+VyWfTB7XaT7nsNPgD10C0o4DPoF4tFLZ/P + axggrV6vi/dCocDCvq5RzLfwDNP3DpMXQLfl9XpNVquVcBTCNQoB+3K53INut3sPiZ9iKt/C + /el2lC8SiUQM12dxOByiZH4ul0sR7PV6xVBtNhsxVJjQm0ajcYXYx7cVHLtcLo4np9MpEvBT + lmVRJsZZVMT9YA183PxjYw9OwA34Ab6BoT5x5zoXYAS+6xrWntz9jf9jPwUYAKt/9B8pRO/y + AAAAAElFTkSuQmCC'! Item was changed: ----- Method: MenuIcons class>>itemsIcons (in category 'menu decoration') ----- itemsIcons "answer a collection of associations wordings -> icon to decorate the menus all over the image" | icons | icons := OrderedCollection new. "icons add: #('Test Runner' ) -> self smallTrafficIcon." " world menu" + "icons add: #('previous project' 'go to previous project') -> self smallProjectBackIcon." - icons add: #('previous project' 'go to previous project') -> self smallProjectBackIcon. icons add: #('go to next project') -> self smallProjectNextIcon. icons add: #('select' ) -> self smallSelectIcon. icons add: #('jump to project...' ) -> self smallProjectJumpIcon. icons add: #('open...' ) -> self smallOpenIcon. icons add: #('appearance...' ) -> self smallConfigurationIcon. icons add: #('help...' ) -> self smallHelpIcon. + "icons add: #('windows...' ) -> self smallWindowIcon." + icons add: #('changes...' ) -> self smallDocumentClockIcon. - icons add: #('windows...' ) -> self smallWindowIcon. - icons add: #('changes...' ) -> self smallChangesIcon. icons add: #('print PS to file...' ) -> self smallPrintIcon. icons add: #('debug...' ) -> self smallDebugIcon. icons add: #('export...' ) -> self smallExportIcon. icons add: #('save' ) -> self smallSaveIcon. + "icons add: #('save project on file...' ) -> self smallProjectSaveIcon." + "icons add: #('save as...') -> self smallSaveAsIcon. - icons add: #('save project on file...' ) -> self smallProjectSaveIcon. - icons add: #('save as...') -> self smallSaveAsIcon. icons add: #('save as new version') -> self smallSaveNewIcon. + icons add: #('save and quit' ) -> self smallQuitIcon." - icons add: #('save and quit' ) -> self smallQuitIcon. icons add: #('quit') -> self smallQuitNoSaveIcon. + "icons add: #('load project from file...' ) -> self smallProjectLoadIcon." - icons add: #('load project from file...' ) -> self smallProjectLoadIcon. "" icons add: #('do it (d)' ) -> self smallDoItIcon. + icons add: #('inspect it (i)' 'inspect world' 'explore world' 'inspect model' 'inspect morph' 'explore morph' 'inspect owner chain' 'explore' 'inspect' 'explore (I)' 'inspect (i)' 'basic inspect' ) -> self smallInspectItIcon. - icons add: #('inspect it (i)' 'explore it (I)' 'inspect world' 'explore world' 'inspect model' 'inspect morph' 'explore morph' 'inspect owner chain' 'explore' 'inspect' 'explore (I)' 'inspect (i)' 'basic inspect' ) -> self smallInspectItIcon. icons add: #('print it (p)' ) -> self smallPrintIcon. icons add: #('debug it' ) -> self smallDebugIcon. icons add: #('tally it' ) -> self smallTimerIcon. "" icons add: #('copy (c)' 'copy to paste buffer' 'copy text' ) -> self smallCopyIcon. + icons add: #('paste (v)') -> self smallPasteIcon. - icons add: #('paste (v)' 'paste...' ) -> self smallPasteIcon. icons add: #('cut (x)' ) -> self smallCutIcon. "" icons add: #('accept (s)' 'yes' 'Yes' ) -> self smallOkIcon. icons add: #('cancel (l)' 'no' 'No' ) -> self smallCancelIcon. "" icons add: #('do again (j)' ) -> self smallRedoIcon. icons add: #('undo (z)' ) -> self smallUndoIcon. "" icons add: #( 'find class... (f)' 'find method...' ) -> self smallSearchIcon. + icons add: #('find...(f)') -> self smallFindIcon. - icons add: #('find...(f)' 'find again (g)') -> self smallFindIcon. "" icons add: #('remove' 'remove class (x)' 'delete method from changeset (d)' 'remove method from system (x)' 'delete class from change set (d)' 'remove class from system (x)' 'destroy change set (X)' ) -> self smallDeleteIcon. icons add: #('add item...' 'new category...' 'new change set... (n)' ) -> self smallNewIcon. "" + icons add: #('objects (o)' ) -> self smallObjectCatalogIcon. - icons add: #('new morph...' 'objects (o)' ) -> self smallObjectCatalogIcon. icons add: #('authoring tools...') -> self smallAuthoringToolsIcon. icons add: #('projects...') -> self smallProjectIcon. "" icons add: #('make screenshot') -> self smallScreenshotIcon. "" icons add: #('leftFlush' ) -> self smallLeftFlushIcon. icons add: #('rightFlush' ) -> self smallRightFlushIcon. icons add: #('centered' 'set alignment... (u)' ) -> self smallCenteredIcon. icons add: #('justified' ) -> self smallJustifiedIcon. "" icons add: #('set font... (k)' 'list font...' 'set subtitles font' 'change font' 'system fonts...' 'change font...' 'default text font...' 'flaps font...' 'eToys font...' 'eToys title font...' 'halo label font...' 'menu font...' 'window-title font...' 'balloon-help font...' 'code font...' 'button font...') -> self smallFontsIcon. icons add: #('full screen on') -> self smallFullscreenOnIcon. icons add: #('full screen off' ) -> self smallFullscreenOffIcon. "" ^ icons! Item was added: + ----- Method: MenuIcons class>>smallBroomIcon (in category 'accessing - icons') ----- + smallBroomIcon + + ^ self fugueBroomIcon! Item was added: + ----- Method: MenuIcons class>>smallDocumentClockIcon (in category 'accessing - icons') ----- + smallDocumentClockIcon + + ^ self fugueDocumentClockIcon! Item was added: + ----- Method: MenuIcons class>>smallUserQuestionIcon (in category 'accessing - icons') ----- + smallUserQuestionIcon + + ^ self fugueUserSilhouetteQuestionIcon! Item was changed: ----- Method: TheWorldMainDockingBar>>extrasMenuOn: (in category 'submenu - extras') ----- extrasMenuOn: aDockingBar aDockingBar addItem: [ :it| it contents: 'Extras' translated; addSubMenu: [:menu| menu addItem:[:item| item contents: 'Recover Changes' translated; help: 'Recover changes after a crash' translated; + icon: MenuIcons smallDocumentClockIcon; - icon: MenuIcons smallHelpIcon; target: ChangeList; selector: #browseRecentLog]. menu addLine. menu addItem:[:item| item contents: 'Window Colors' translated; help: 'Changes the window color scheme' translated; addSubMenu:[:submenu| self windowColorsOn: submenu]]. menu addItem:[:item| item contents: 'Set Author Initials' translated; help: 'Sets the author initials' translated; + icon: MenuIcons smallUserQuestionIcon; target: Utilities; selector: #setAuthorInitials]. menu addItem:[:item| item contents: 'Restore Display (r)' translated; help: 'Redraws the entire display' translated; target: World; selector: #restoreMorphicDisplay]. menu addItem:[:item| item contents: 'Rebuild Menus' translated; help: 'Rebuilds the menu bar' translated; target: TheWorldMainDockingBar; selector: #updateInstances]. menu addLine. menu addItem:[:item| item contents: 'Start Profiler' translated; help: 'Starts the profiler' translated; + icon: MenuIcons smallTimerIcon; target: self; selector: #startMessageTally]. menu addItem:[:item| item contents: 'Collect Garbage' translated; help: 'Run the garbage collector and report space usage' translated; target: Utilities; selector: #garbageCollectAndReport]. menu addItem:[:item| item contents: 'Purge Undo Records' translated; help: 'Save space by removing all the undo information remembered in all projects' translated; target: CommandHistory; selector: #resetAllHistory]. menu addItem:[:item| item contents: 'VM statistics' translated; help: 'Virtual Machine information' translated; target: self; selector: #vmStatistics]. menu addLine. menu addItem:[:item| item contents: 'Graphical Imports' translated; help: 'View the global repository called ImageImports; you can easily import external graphics into ImageImports via the FileList' translated; target: (Imports default); selector: #viewImages]. menu addItem:[:item| item contents: 'Standard Graphics Library' translated; help: 'Lets you view and change the system''s standard library of graphics' translated; target: ScriptingSystem; selector: #inspectFormDictionary]. menu addItem:[:item| item contents: 'Annotation Setup' translated; help: 'Click here to get a little window that will allow you to specify which types of annotations, in which order, you wish to see in the annotation panes of browsers and other tools' translated; target: Preferences; selector: #editAnnotations]. menu addItem:[:item| item contents: 'Browse My Changes' translated; help: 'Browse all of my changes since the last time #condenseSources was run.' translated; target: SystemNavigation new; selector: #browseMyChanges]. ] ]! Item was changed: ----- Method: TheWorldMainDockingBar>>listWindowsOn: (in category 'submenu - windows') ----- listWindowsOn: menu | windows | windows := SortedCollection sortBlock: [:winA :winB | winA model name = winB model name ifTrue: [winA label < winB label] ifFalse: [winA model name < winB model name]]. windows addAll: self allVisibleWindows. windows ifEmpty: [ menu addItem: [ :item | item contents: 'No Windows' translated; isEnabled: false ] ]. windows do: [ :each | menu addItem: [ :item | item contents: (self windowMenuItemLabelFor: each); icon: (self colorIcon: each model defaultBackgroundColor); target: each; selector: #comeToFront; subMenuUpdater: self selector: #windowMenuFor:on: arguments: { each }; action: [ each activateAndForceLabelToShow; expand ] ] ]. menu addLine; add: 'Close all windows' target: self selector: #closeAllWindowsUnsafe; + addItem: [:item | item + contents: 'Close all windows without changes'; + target: self; + icon: MenuIcons smallBroomIcon; + selector: #closeAllWindows]; - add: 'Close all windows without changes' target: self selector: #closeAllWindows; add: 'Close all windows but workspaces' target: self selector: #closeAllWindowsButWorkspaces.! Item was changed: ----- Method: TheWorldMainDockingBar>>loadProjectMenuItemOn: (in category 'submenu - projects') ----- loadProjectMenuItemOn: menu menu addItem: [ :item | item contents: 'Load Project' translated; help: 'Load a project from a file' translated; - icon: MenuIcons smallProjectLoadIcon; target: self; selector: #loadProject ]! Item was changed: ----- Method: TheWorldMainDockingBar>>previousProjectMenuItemOn: (in category 'submenu - projects') ----- previousProjectMenuItemOn: menu menu addItem: [ :item | item contents: 'Previous Project' translated; help: 'Return to the most-recently-visited project' translated; - icon: MenuIcons smallProjectBackIcon; target: World; selector: #goBack ]! Item was changed: ----- Method: TheWorldMainDockingBar>>projectsMenuOn: (in category 'construction') ----- projectsMenuOn: aDockingBar aDockingBar addItem: [ :item | item contents: 'Projects' translated; addSubMenu: [ :menu | + self newProjectMenuItemOn: menu. + menu addLine. self - newProjectMenuItemOn: menu; saveProjectMenuItemOn: menu; + loadProjectMenuItemOn: menu. + menu addLine. + self - loadProjectMenuItemOn: menu; previousProjectMenuItemOn: menu; jumpToProjectMenuItemOn: menu ] ] ! Item was changed: ----- Method: TheWorldMainDockingBar>>saveAndQuitMenuItemOn: (in category 'submenu - squeak') ----- saveAndQuitMenuItemOn: menu menu addItem: [ :item | item contents: 'Save And Quit' translated; help: 'Save the current state of Squeak on disk, and quit out of Squeak' translated; - icon: MenuIcons smallQuitIcon; target: self; selector: #saveAndQuitSqueak ]! Item was changed: ----- Method: TheWorldMainDockingBar>>saveAsMenuItemOn: (in category 'submenu - squeak') ----- saveAsMenuItemOn: menu menu addItem: [ :item | item + contents: 'Save As...' translated; - contents: 'Save Image As...' translated; help: 'Save the current state of Squeak on disk under a new name' translated; - icon: MenuIcons smallSaveAsIcon; target: self; selector: #saveImageAs ]! Item was changed: ----- Method: TheWorldMainDockingBar>>saveAsNewVersionMenuItemOn: (in category 'submenu - squeak') ----- saveAsNewVersionMenuItemOn: menu menu addItem: [ :item | item contents: 'Save As New Version' translated; help: 'Save the current state of Squeak on disk under a version-stamped name' translated; - icon: MenuIcons smallSaveNewIcon; target: self; selector: #saveAsNewVersion ]! Item was changed: ----- Method: TheWorldMainDockingBar>>saveMenuItemOn: (in category 'submenu - squeak') ----- saveMenuItemOn: menu menu addItem: [ :item | item + contents: 'Save' translated; - contents: 'Save Image' translated; help: 'Save the current state of Squeak on disk' translated; icon: MenuIcons smallSaveIcon; target: self; selector: #saveImage ]! Item was changed: ----- Method: TheWorldMainDockingBar>>saveProjectMenuItemOn: (in category 'submenu - projects') ----- saveProjectMenuItemOn: menu menu addItem: [ :item | item contents: 'Save Project' translated; help: 'Save this project on a file' translated; - icon: MenuIcons smallProjectSaveIcon; target: World; selector: #saveOnFile ]! Item was changed: ----- Method: TheWorldMainDockingBar>>updateMenuItemOn: (in category 'submenu - squeak') ----- updateMenuItemOn: menu menu addItem: [ :item | item contents: 'Update Squeak' translated; help: 'Load latest code updates via the internet' translated; + icon: MenuIcons smallChangesIcon; target: self; selector: #updateSqueak ]! Item was changed: (PackageInfo named: 'Morphic') postscript: '"Initialize the key bindings and menus" Editor initialize. "apply the new icons" MenuIcons initializeIcons. TheWorldMainDockingBar updateInstances. + "Fix missing inset of old-style windows." - "Fix missing inset of open windows." SystemWindow allSubInstancesDo: [:ea | + (ea paneMorphs detect: [:m | m layoutFrame leftFraction = 0] ifNone: []) + ifNotNil: [:m | m layoutFrame leftOffset > 0 + ifTrue: [ea layoutInset: 0]]]. + + "Remove non-functional tools from world menu." + LanguageEditor unload. + UUniverseBrowser unload. + UUniverseEditor unload.'! - ea - wantsPaneSplitters: true; - layoutInset: ProportionalSplitterMorph gripThickness; - cellInset: ProportionalSplitterMorph gripThickness]. - - "Update minimum extents and clipping." - PluggableButtonMorph allSubInstancesDo: [:ea | - ea - clipSubmorphs: true; - updateMinimumExtent].'! From juanlists at jvuletich.org Sun May 10 19:08:25 2015 From: juanlists at jvuletich.org (J. Vuletich (mail lists)) Date: Sun May 10 19:08:29 2015 Subject: [squeak-dev] Re: [Pharo-dev] A fast Transcript In-Reply-To: References: Message-ID: <20150510190825.Horde.RJYq6hoJRU4tvFn-ASKO6Q1@gator3294.hostgator.com> Hi Eliot, Today I woke up with a simple idea: In Cuis' Transcript, once you do "Workspace with contents", keep a reference to that workspace, and add new Transcript stuff to it. This is done afterwards, when Morphic runs again. Immediate Transcript update is not affected. The effect is like having an editable Transcript, with a fast, immediate "preview" in a separate window. I just did a commit to the Cuis Github repo with this (amongst a lot of other changes). Please try it and tell if this simple solution is enough for your needs. OT: BTW, I added a new VMMaker package. It is a verbatim copy of the latest VMMaker in http://source.squeak.org/VMMaker/ . I didn't change a single line of code (except for one method in GeniePlugin that seems to break some compiler limit). It can generate all the plugins. This is all I tested so far. The GUI is not functional, due to the differences in Morphic. But at least there are no Undeclared. Cheers, Juan Vuletich www.cuis-smalltalk.org https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev Quoting Eliot Miranda : > Hi Juan, > > I see that your new transcript is indeed much faster but is also not > editable. I wonder if it would be possible to have the best of both worlds > and arrange that, when active, the transcript is editable. For example, > selecting the TranscriptWIndow could put it into a mode where the > transcript's state was imported into a more conventional editable text > morph, and then when the window was exited, reverted to the standard fast > output mode. As you can infer I like having an editable transcript. I can > do without it, because Squeak's slow transcript is indeed a PITA, but I'm > not sure that speed need preclude editability. > > On Sat, May 9, 2015 at 10:17 AM, J. Vuletich (mail lists) < > juanlists@jvuletich.org> wrote: > >> Hi Folks, >> >> (below) >> >> >> Quoting Ben Coman : >> >> On Sat, May 9, 2015 at 10:35 PM, Eliot Miranda >>> wrote: >>> >>> >>>> >>>> On Sat, May 9, 2015 at 7:09 AM, Ben Coman wrote: >>>> >>>> From my limited experience bug hunting, calling #changed: from a thread >>>>> other than the UI thread is a source of evil. There are too many >>>>> assumptions throughout the system that the UI is single threaded. Can >>>>> anyone advise me that is not a proper belief? >>>>> >>>>> Then that implies that a Transcript implementation where #nextPut: >>>>> direct >>>>> calls #changed: >>>>> is not appropriate for use with multi-threaded applications. In Pharo, >>>>> #changed: is only called from #stepGlobal, which is called from >>>>> doOneCycle:. (This came about as a last minute bug fix before Pharo 3 >>>>> release and maybe could use some cleanup. >>>>> >>>>> Separating the UI from Transcript into its own viewer might be a good >>>>> idea, but actually it would not solve Stef's case since his code would >>>>> still be running in the UI thread -- unless the viewer ran in another >>>>> thread, which would have its own complexities. >>>>> >>>>> I think the point about efficiency is significant. The following >>>>> example... >>>>> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: 'x' >>>>> ] ] >>>>> on Squeak 4.5 --> 12749ms >>>>> on Pharo 50029 --> 2ms >>>>> >>>>> This better performance helped me a lot trying to understand the high >>>>> priority timerEventLoop being able to indiscriminately scatter >>>>> Transcript >>>>> tracing through that code. I believe its also probably beneficial for >>>>> working with externally triggered semaphores and timing sensitive race >>>>> conditions. >>>>> >>>>> So we have two mutually exclusive cases: >>>>> * better interactivity, poorer system performance >>>>> * faster system performance, worse interactivity >>>>> >>>>> Which of these is broken depends on your viewpoint. >>>>> >>>>> >>>> Something that runs fast but is incorrect is still incorrect. The fact >>>> that the transcript doesn't output until a world step is possible is a >>>> bug. It forces programs that use the transcript to be rewritten in order >>>> to see transcript output. >>>> >>>> >>> As a point of comparison for correctness, for the following... >>> >>> Transcript clear. >>> [ $a asciiValue to: $z asciiValue do: [ :c | >>> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter printString , i >>> printString , ' ' ] ] forkAt: 40 >>> ]. >>> ] forkAt: 41 >>> >>> Squeak 4.5 gives... >>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b5 $c1 $c2 $c3 >>> $c4 >>> $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $d9 $e2 $g2 $h2 >>> $h2 >>> $i2 $k2 $k2 $l2 $n2 $n2 $o2 $o2 $r2 $s2 $t2 $u2 $u2 $v2 $x2 $y2 $z2 $z2 >>> $b7 >>> $f3 $e3 $e3 $g3 $j3 $h3 $i3 $k3 $k3 $m3 $n3 $p3 $p3 $q3 $o3 $s3 $t3 $t3 >>> $u3 >>> $v3 $x3 $y3 $z3 $b8 $f4 $e4 $e4 $g4 $h4 $i4 $k4 $l4 $m4 $m4 $n4 $r4 $q4 >>> $o4 >>> $o4 $s4 $w4 $u4 $u4 $v4 $y4 $y4 $z4 $z4 $f5 $j5 $j5 $g5 $i5 $k5 $l5 $l5 >>> $m5 >>> $m5 $n5 $q5 $o5 $s5 $s5 $t5 $u5 $u5 $x5 $y5 $z5 $f6 $f6 $h6 $h6 $g6 $g6 >>> $k6 >>> $p6 $m6 $r6 $r6 $n6 $o6 $s6 $s6 $w6 $u6 $x6 $x6 $e7 $f7 $j7 $h7 $h7 $i7 >>> $l7 >>> $l7 $k7 $m7 $m7 $q7 $n7 $n7 $o7 $t7 $w7 $w7 $u7 $v7 $x7 $z7 $z7 $e8 $e8 >>> $h8 >>> $g8 $i8 $i8 $l8 $k8 $k8 $m8 $q8 $n8 $n8 $s8 $t8 $w8 $y8 $y8 $u8 $x8 $z8 >>> $f9 >>> $f9 $e9 $h9 $h9 $g9 $p9 $p9 $k9 $r9 $r9 $m9 $n9 $n9 $o9 $t9 $t9 $w9 $v9 >>> $u9 >>> $u9 $z9 $x9 >>> >>> Pharo 50041 gives... >>> $a1 $a2 $a3 $a4 $a5 $a6 $a7 $a8 $a9 $b1 $b2 $b3 $b4 $b5 $b6 $b7 $b8 $b9 >>> $c1 >>> $c2 $c3 $c4 $c5 $c6 $c7 $c8 $c9 $d1 $d2 $d3 $d4 $d5 $d6 $d7 $d8 $d9 $e1 >>> $e2 >>> $e3 $e4 $e5 $e6 $e7 $e8 $e9 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $g1 $g2 >>> $g3 >>> $g4 $g5 $g6 $g7 $g8 $g9 $h1 $h2 $h3 $h4 $h5 $h6 $h7 $h8 $h9 $i1 $i2 $i3 >>> $i4 >>> $i5 $i6 $i7 $i8 $i9 $j1 $j2 $j3 $j4 $j5 $j6 $j7 $j8 $j9 $k1 $k2 $k3 $k4 >>> $k5 >>> $k6 $k7 $k8 $k9 $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8 $l9 $m1 $m2 $m3 $m4 $m5 >>> $m6 >>> $m7 $m8 $m9 $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $o1 $o2 $o3 $o4 $o5 $o6 >>> $o7 >>> $o8 $o9 $p1 $p2 $p3 $p4 $p5 $p6 $p7 $p8 $p9 $q1 $q2 $q3 $q4 $q5 $q6 $q7 >>> $q8 >>> $q9 $r1 $r2 $r3 $r4 $r5 $r6 $r7 $r8 $r9 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $s8 >>> $s9 >>> $t1 $t2 $t3 $t4 $t5 $t6 $t7 $t8 $t9 $u1 $u2 $u3 $u4 $u5 $u6 $u7 $u8 $u9 >>> $v1 >>> $v2 $v3 $v4 $v5 $v6 $v7 $v8 $v9 $w1 $w2 $w3 $w4 $w5 $w6 $w7 $w8 $w9 $x1 >>> $x2 >>> $x3 $x4 $x5 $x6 $x7 $x8 $x9 $y1 $y2 $y3 $y4 $y5 $y6 $y7 $y8 $y9 $z1 $z2 >>> $z3 >>> $z4 $z5 $z6 $z7 $z8 $z9 >>> >>> (start your comparison at $b5) >>> >>> So in one axis Pharo has improved Transcript, but we didn't notice the >>> significance of the use case we lost. >>> >>> cheers -ben >>> >> >> Please take a good look at Cuis' Transcript and consider using it. >> >> By default, the display is updated immediately, but without calling >> Morphic, it can even work with no UI framework at all. It does updates >> faster than Squeak or Visualworks: >> >> Time millisecondsToRun: [ 1000 timesRepeat: [ Transcript show: >> 'x' ] ]. 763. >> >> But if you want minimum overhead without immediate feedback: >> >> Time millisecondsToRun: [ Transcript showOnDisplay: false. 1000 >> timesRepeat: [ Transcript show: 'x' ]. Transcript showOnDisplay: true ]. 1. >> "As fast as Pharo" >> >> It is also thread safe, and for Ben's example: >> >> Transcript clear. >> [ >> $a asciiValue to: $z asciiValue do: [ :c | >> [ 1 to: 9 do: [ :i | Transcript show: c asCharacter >> printString , i printString , ' ' ] ] forkAt: 40 >> ]. >> ] forkAt: 41 >> >> it gives the same result as Pharo. >> >> The fact that the updates are not bound to Morphic also means that it is >> possible to do #show: deep in Morphic logic, without causing infinite loops >> or recursions, and get immediate feedback. It has proved to be a useful aid >> in debugging Morphic code. >> >> Cheers, >> Juan Vuletich >> >> >> > > > -- > best, > Eliot From eliot.miranda at gmail.com Sun May 10 20:53:02 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sun May 10 20:53:07 2015 Subject: [squeak-dev] New Cog VMs available Message-ID: ... at http://www.mirandabanda.org/files/Cog/VM/VM.r3326. CogVM binaries as per VMMaker.oscog-eem.1297/r3326 NewspeakVM: Thread lookup rule through from bytecodes to internalFindNewMethod:. Fix genInnerPrimitiveMirrorNewWithArg:. Class's hash was being accessed twice, reusing variable holding jump instruction. Fix primitiveClass and genPrimitiveClass for mirror case (arg count = 1). Also fix Newspeak primitive table to allow nargs > 0 for genPrimitiveClass. General: Fix a regression in externalInstVar:ofContext:. The head frame pointers must be written back if we're going to map a machince code pc to a bytecode pc in case of code reclamation. Add asserts to the stack page enumerators to check that the head frame pointers have been written back. Use macros for the oop comparisons, avoiding cCoerce:, to get faster simulation and avoid the inliner not inlining in conditionals. Spur: Change computeRefCountToShrinkRT to - compute the ref counts and population in a single pass over the RT - determine the ref count for tenuring based on half the population of remembered objects, /not/ half the size of the RT. Sista: Remove the storeCheck in inlined pointer at:put: if the value stored is an unannotatable constant. Increased the opcode size heuristic in the SistaCogit. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150510/14396927/attachment.htm From asqueaker at gmail.com Sun May 10 21:29:38 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sun May 10 21:29:41 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: <1431180976415-4825440.post@n4.nabble.com> References: <1431180976415-4825440.post@n4.nabble.com> Message-ID: On Sat, May 9, 2015 at 9:16 AM, marcel.taeumel wrote: > You separate patterns with ";". Multi-line just because it now wraps again. > > Could you hit return in the past? Yes, just as you can on virtually any "Search" field of any system anywhere on the planet, including our own Search field on our Docking Bar. > I thought that's why the "Search" button > was there. Would you please start including gesture counts of various use-cases into your UI changes? For MessageNames the use-case is multiple successive searches, as in, I didn't find the results I'm looking for the first or second time, but now you're forcing the user to move their hands back and forth between the keyboard and mouse just to click that Search button. This is significant degradation in the usability of this window. You said search terms are separated by semicolons so what value do CR's provide by being in the input? From commits at source.squeak.org Sun May 10 21:55:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 21:55:06 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150510215505.25362.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008338.html Name: SUnitGUI-mt.62 Ancestors: SUnitGUI-topa.61 Upper spacing of button bar in test runner fixed by removing some magic numbers. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008339.html Name: HelpSystem-Core-mt.74 Ancestors: HelpSystem-Core-mt.73 Added support for ignoring class-based help topics. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008340.html Name: Help-Squeak-SWiki-mt.2 Ancestors: Help-Squeak-SWiki-mt.1 Only support opening SWiki in HelpBrowser directly. Ignore it if embedded in other help structures. SWiki help integration is still experimental and should not confuse other users. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008341.html Name: GetText-mt.37 Ancestors: GetText-nice.36 Skip registering LanguageEditor in world menu for now because it is not functional at the moment. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008342.html Name: Universes-mt.48 Ancestors: Universes-kfr.47 Skip registering Universe tools in the world menu because they are not functional at the moment. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008343.html Name: Graphics-mt.313 Ancestors: Graphics-mt.312 Conveniently adjust saturation or brightness of forms. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008344.html Name: Collections-mt.635 Ancestors: Collections-ul.634 Some debug code removed from html readwriter.. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008345.html Name: Morphic-mt.975 Ancestors: Morphic-mt.974 Reduced/updated icon usage in menus to make those other icons more effective. Postscript unloads menu entries for universe tools and language editor tools because those are not functional the moment. ============================================= From commits at source.squeak.org Sun May 10 22:03:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 22:03:15 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.976.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.976.mcz ==================== Summary ==================== Name: Morphic-cmm.976 Author: cmm Time: 10 May 2015, 5:02:21.338 pm UUID: f38aa89b-6570-4bc3-9113-b2bf193475ca Ancestors: Morphic-mt.975 Added preference to let Command+0 jump straight to the new results balloon of the search bar, where pressing ESCape returns keyboard focus to the originating window. =============== Diff against Morphic-mt.975 =============== Item was changed: Model subclass: #SearchBar + instanceVariableNames: 'originatingWidget searchTerm selection resultsWidget workspace scratchPad' + classVariableNames: 'UseScratchPad' - instanceVariableNames: 'searchTerm selection resultsWidget workspace' - classVariableNames: '' poolDictionaries: '' category: 'Morphic-Menus-DockingBar'! Item was added: + ----- Method: SearchBar class>>useScratchPad (in category 'preferences') ----- + useScratchPad + + ^ UseScratchPad ifNil: [ false ]! Item was added: + ----- Method: SearchBar class>>useScratchPad: (in category 'preferences') ----- + useScratchPad: aBoolean + UseScratchPad := aBoolean! Item was changed: ----- Method: SearchBar>>activate:in: (in category 'accessing') ----- + activate: event in: morph + UseScratchPad + ifTrue: + [ event hand keyboardFocus = self scratchPad ifFalse: [ originatingWidget := event hand keyboardFocus ]. + self scratchPad selectAll; openInWorld. + event hand newKeyboardFocus: self scratchPad ] + ifFalse: + [ self selection: (1 to: self searchTerm size). + event hand newKeyboardFocus: morph textMorph ]! - activate: event in: morph - - self selection: (1 to: self searchTerm size). - event hand newKeyboardFocus: morph textMorph.! Item was added: + ----- Method: SearchBar>>handleScratchPadKey: (in category 'private') ----- + handleScratchPadKey: aKeyboardEvent + (aKeyboardEvent keyValue = Character escape asciiValue and: [ originatingWidget notNil ]) ifTrue: + [ aKeyboardEvent hand newKeyboardFocus: originatingWidget. + self removeScratchPad ]! Item was added: + ----- Method: SearchBar>>removeScratchPad (in category 'accessing') ----- + removeScratchPad + scratchPad ifNotNil: [ scratchPad delete ]! Item was added: + ----- Method: SearchBar>>scratchPad (in category 'accessing') ----- + scratchPad + ^ scratchPad ifNil: + [ | pos width | + World mainDockingBars do: + [ : each | each searchBarMorph ifNotNil: + [ : searchBar | pos := searchBar bottomLeft. width:=searchBar width ] ]. + width ifNil: [ width:=250. pos := World topRight - (width @ 5) ]. + scratchPad := TextMorph new. + scratchPad + on: #keyboardFocusChange send: #removeScratchPad to: self ; + on: #mouseLeave send: #removeScratchPad to: self ; + on: #keyStroke send: #handleScratchPadKey: to: self ; + backgroundColor: (BalloonMorph balloonColor alpha: 1.0) ; + width: width ; + autoFit: true ; + wrapFlag: true ; + newContents: '--scratch area--' ; + yourself. + scratchPad position: pos. + Preferences menuAppearance3d ifTrue: [ scratchPad addDropShadow ]. + scratchPad ]! From commits at source.squeak.org Sun May 10 22:07:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 22:07:29 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.977.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.977.mcz ==================== Summary ==================== Name: Morphic-cmm.977 Author: cmm Time: 10 May 2015, 5:06:29.825 pm UUID: 2f407c53-906b-4ba2-a818-b94723dbea9f Ancestors: Morphic-cmm.976 Support the "Typing Blind" use case when Auto Enclose is enabled. =============== Diff against Morphic-cmm.976 =============== Item was changed: ----- Method: TextEditor>>dispatchOnKeyboardEvent: (in category 'typing support') ----- + dispatchOnKeyboardEvent: aKeyboardEvent + "Carry out the action associated with this character, if any. Type-ahead is passed so some routines can flush or use it." + | honorCommandKeys openers closers result typedChar | + ((typedChar := aKeyboardEvent keyCharacter) == Character cr and: [ morph acceptOnCR ]) ifTrue: + [ self closeTypeIn. + ^ true ]. - dispatchOnKeyboardEvent: aKeyboardEvent - "Carry out the action associated with this character, if any. - Type-ahead is passed so some routines can flush or use it." - - | honorCommandKeys openers closers result | - (aKeyboardEvent keyCharacter == Character cr and: [ morph acceptOnCR ]) - ifTrue: [ - self closeTypeIn. - ^ true ]. self clearParens. + aKeyboardEvent keyValue = 13 ifTrue: + [ aKeyboardEvent controlKeyPressed ifTrue: [ ^ self normalCharacter: aKeyboardEvent ]. + aKeyboardEvent shiftPressed ifTrue: [ ^ self lf: aKeyboardEvent ]. + aKeyboardEvent commandKeyPressed ifTrue: [ ^ self crlf: aKeyboardEvent ]. + ^ self crWithIndent: aKeyboardEvent ]. + ((honorCommandKeys := Preferences cmdKeysInText) and: [ typedChar = Character enter ]) ifTrue: [ ^ self dispatchOnEnterWith: aKeyboardEvent ]. + "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this - aKeyboardEvent keyValue = 13 - ifTrue: [ - aKeyboardEvent controlKeyPressed - ifTrue: [ ^ self normalCharacter: aKeyboardEvent ]. - aKeyboardEvent shiftPressed - ifTrue: [ ^ self lf: aKeyboardEvent ]. - aKeyboardEvent commandKeyPressed - ifTrue: [ ^ self crlf: aKeyboardEvent ]. - ^ self crWithIndent: aKeyboardEvent ]. - ((honorCommandKeys := Preferences cmdKeysInText) and: [ aKeyboardEvent keyCharacter = Character enter ]) - ifTrue: [ ^ self dispatchOnEnterWith: aKeyboardEvent ]. "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this conflict, assume that keys other than cursor keys aren't used together with Crtl." + ((self class specialShiftCmdKeys includes: aKeyboardEvent keyValue) and: [ aKeyboardEvent keyValue < 27 ]) ifTrue: [ ^ aKeyboardEvent controlKeyPressed + ifTrue: + [ self + perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) + with: aKeyboardEvent ] + ifFalse: + [ self + perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) + with: aKeyboardEvent ] ]. + "backspace, and escape keys (ascii 8 and 27) are command keys" + ((honorCommandKeys and: [ aKeyboardEvent commandKeyPressed ]) or: [ self class specialShiftCmdKeys includes: aKeyboardEvent keyValue ]) ifTrue: [ ^ aKeyboardEvent shiftPressed + ifTrue: + [ self + perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) + with: aKeyboardEvent ] + ifFalse: + [ self + perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) + with: aKeyboardEvent ] ]. + "the control key can be used to invoke shift-cmd shortcuts" + (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ]) ifTrue: [ ^ self + perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) + with: aKeyboardEvent ]. - ((self class specialShiftCmdKeys includes: aKeyboardEvent keyValue) and: [ aKeyboardEvent keyValue < 27 ]) - ifTrue: [ - ^ aKeyboardEvent controlKeyPressed - ifTrue: [ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] - ifFalse: [ self perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ]. "backspace, and escape keys (ascii 8 and 27) are command keys" - ((honorCommandKeys and: [ aKeyboardEvent commandKeyPressed ]) - or: [ self class specialShiftCmdKeys includes: aKeyboardEvent keyValue ]) - ifTrue: [ - ^ aKeyboardEvent shiftPressed - ifTrue: [ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] - ifFalse: [ self perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ]. "the control key can be used to invoke shift-cmd shortcuts" - (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ]) - ifTrue: [ ^ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ]. openers := '([{'. closers := ')]}'. + (closers includes: typedChar) + ifTrue: + [ self blinkPrevParen: typedChar. + self nextNonwhitespaceCharacter = typedChar + ifTrue: + [ self moveCursor: [ : position | position + 1 ] forward: true select: false. + ^ false ] + ifFalse: [ result := self normalCharacter: aKeyboardEvent ] ] + ifFalse: [ result := self normalCharacter: aKeyboardEvent ]. + (self class autoEnclose and: [ openers includes: typedChar ]) ifTrue: + [ self + addString: (closers at: (openers indexOf: typedChar)) asString ; + insertTypeAhead ; + + moveCursor: + [ : position | position - 1 ] + forward: false + select: false ]. - result := self normalCharacter: aKeyboardEvent. - (closers includes: aKeyboardEvent keyCharacter) - ifTrue: [ self blinkPrevParen: aKeyboardEvent keyCharacter]. - (self class autoEnclose and: [ openers includes: aKeyboardEvent keyCharacter ]) - ifTrue: [ - self - addString: (closers at: (openers indexOf: aKeyboardEvent keyCharacter)) asString; - insertTypeAhead ; - - moveCursor: [ :position | position - 1 ] - forward: false - select: false ]. ^ result! Item was added: + ----- Method: TextEditor>>nextNonwhitespaceCharacter (in category 'private') ----- + nextNonwhitespaceCharacter + pointBlock stringIndex + to: paragraph string size + do: + [ : n | | char | (char := paragraph string at: n) isSeparator ifFalse: [ ^ char ] ]. + ^ nil! From commits at source.squeak.org Sun May 10 23:09:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 23:09:31 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.978.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.978.mcz ==================== Summary ==================== Name: Morphic-cmm.978 Author: cmm Time: 10 May 2015, 6:08:38.51 pm UUID: 9ad94f31-56d8-45a5-83e9-47d58671e4ba Ancestors: Morphic-cmm.977 Provide programmatic access to the users preferred clock format in the docking bar. =============== Diff against Morphic-cmm.977 =============== Item was changed: Object subclass: #TheWorldMainDockingBar instanceVariableNames: '' + classVariableNames: 'Instance TS TwentyFourHourClock' - classVariableNames: 'Instance TS' poolDictionaries: '' category: 'Morphic-Kernel'! Item was added: + ----- Method: TheWorldMainDockingBar class>>twentyFourHourClock (in category 'preferences') ----- + twentyFourHourClock + + ^ TwentyFourHourClock ifNil: [ true ]! Item was added: + ----- Method: TheWorldMainDockingBar class>>twentyFourHourClock: (in category 'preferences') ----- + twentyFourHourClock: aBoolean + TwentyFourHourClock := aBoolean. + self updateInstances! Item was changed: ----- Method: TheWorldMainDockingBar>>clockOn: (in category 'right side') ----- clockOn: aDockingBar aDockingBar + addMorphBack: (ClockMorph new show24hr: TwentyFourHourClock; yourself); - addMorphBack: (ClockMorph new show24hr: true; yourself); addDefaultSpace! From commits at source.squeak.org Sun May 10 23:44:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 23:44:30 2015 Subject: [squeak-dev] The Inbox: MonticelloConfigurations-dtl.132.mcz Message-ID: David T. Lewis uploaded a new version of MonticelloConfigurations to project The Inbox: http://source.squeak.org/inbox/MonticelloConfigurations-dtl.132.mcz ==================== Summary ==================== Name: MonticelloConfigurations-dtl.132 Author: dtl Time: 10 May 2015, 12:46:15.656 pm UUID: 5cee23dd-fe38-41b9-afe0-25fb80f6ede7 Ancestors: MonticelloConfigurations-dtl.131 Fix updating from streams other than the default. For example: MCMcmUpdater updateFromRepository: 'http://www.squeaksource.com/OSProcess' baseName: 'update' =============== Diff against MonticelloConfigurations-dtl.131 =============== Item was added: + ----- Method: MCMcmUpdater class>>defaultBaseName (in category 'updating') ----- + defaultBaseName + "If not otherwise specified, look for update maps with this base name" + + ^ 'update'! Item was added: + ----- Method: MCMcmUpdater class>>updateFromRepository: (in category 'updating') ----- + updateFromRepository: updaterUrlKey + "Update using an MCMcmUpdater identified by updaterUrlKey using the default + update map baseName" + + ^ self updateFromRepository: updaterUrlKey baseName: self defaultBaseName + ! Item was added: + ----- Method: MCMcmUpdater class>>updateFromRepository:baseName: (in category 'updating') ----- + updateFromRepository: updaterUrlKey baseName: baseName + "Update using an MCMcmUpdater identified by updaterUrlKey, and using + update map baseName" + + ^ (self updateMapName: baseName repository: updaterUrlKey) + updateFrom: updaterUrlKey! Item was changed: ----- Method: MCMcmUpdater class>>updateFromServer (in category 'updating') ----- updateFromServer "Update the image by loading all pending updates from the server." + ^self default updateFrom: self defaultUpdateURL - ^self default updateFromServer ! Item was removed: - ----- Method: MCMcmUpdater class>>updateUsing:baseName: (in category 'updating') ----- - updateUsing: updaterUrlKey baseName: baseName - "Update using an MCMcmUpdater identified by updaterUrlKey, and using - update map baseName" - - ^ (self updateMapName: baseName repository: updaterUrlKey) updateFromServer - ! Item was added: + ----- Method: MCMcmUpdater>>updateFrom: (in category 'updating') ----- + updateFrom: url + "Update the image by loading all pending updates from the server." + | config | + "Flush all caches. If a previous download failed this is often helpful" + MCFileBasedRepository flushAllCaches. + config := self updateFromRepositories: { url }. + config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. + config setSystemVersion. + self inform: ('Update completed. + Current update number: ' translated, SystemVersion current highestUpdate).! Item was removed: - ----- Method: MCMcmUpdater>>updateFromServer (in category 'updating') ----- - updateFromServer - "Update the image by loading all pending updates from the server." - | config | - "Flush all caches. If a previous download failed this is often helpful" - MCFileBasedRepository flushAllCaches. - config := MCMcmUpdater default updateFromDefaultRepository. - config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. - config setSystemVersion. - self inform: ('Update completed. - Current update number: ' translated, SystemVersion current highestUpdate).! From commits at source.squeak.org Sun May 10 23:44:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 10 23:44:46 2015 Subject: [squeak-dev] The Inbox: MonticelloConfigurations-dtl.133.mcz Message-ID: David T. Lewis uploaded a new version of MonticelloConfigurations to project The Inbox: http://source.squeak.org/inbox/MonticelloConfigurations-dtl.133.mcz ==================== Summary ==================== Name: MonticelloConfigurations-dtl.133 Author: dtl Time: 10 May 2015, 7:38:29.29 pm UUID: d5d2f00e-20d2-4e1e-bb26-6f087e3d9c28 Ancestors: MonticelloConfigurations-dtl.132 MCMcmUpdater>>refreshUpdateMapFor:with: should not answer an empty update list in the case of a package that has not yet been loaded. Fixes an existing bug, not related to the refactoring in the last two updates. =============== Diff against MonticelloConfigurations-dtl.132 =============== Item was changed: ----- Method: MCMcmUpdater>>refreshUpdateMapFor:with: (in category 'updating') ----- refreshUpdateMapFor: r with: updateList "Update the lastUpdateMap and answer a possibly reduced updateList" | config | (lastUpdateMap at: r description ifAbsent: [0]) = 0 ifTrue: [ "No update has ever been loaded from this repo. If no package is present in the image either, we can skip right to the latest config" config := r versionNamed: updateList last value. + (config dependencies anySatisfy: [:dep | dep package hasWorkingCopy]) + ifFalse: [(self useLatestPackagesFrom: r) + ifTrue: [lastUpdateMap at: r description put: updateList last key]. + updateList isEmpty + ifTrue: [^ #()] + ifFalse: [^ updateList last: 1]]]. - (config dependencies anySatisfy: [:dep| dep package hasWorkingCopy]) - ifFalse: [ (self useLatestPackagesFrom: r) - ifTrue: [lastUpdateMap at: r description put: updateList last key. - ^ #()] - ifFalse: [ ^ updateList last: 1]]]. ^ updateList ! From lewis at mail.msen.com Mon May 11 00:07:15 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Mon May 11 00:07:17 2015 Subject: [squeak-dev] Fixing a problem for SqueakMap and Spur for the 5.0 release (was: The Inbox: MonticelloConfigurations-dtl.132.mcz) In-Reply-To: <201505102344.t4ANiVhh062516@shell.msen.com> References: <201505102344.t4ANiVhh062516@shell.msen.com> Message-ID: <20150511000715.GA62795@shell.msen.com> On Sun, May 10, 2015 at 11:44:25PM +0000, commits@source.squeak.org wrote: > David T. Lewis uploaded a new version of MonticelloConfigurations to project The Inbox: > http://source.squeak.org/inbox/MonticelloConfigurations-dtl.132.mcz > > ==================== Summary ==================== > > Name: MonticelloConfigurations-dtl.132 > Author: dtl > Time: 10 May 2015, 12:46:15.656 pm > UUID: 5cee23dd-fe38-41b9-afe0-25fb80f6ede7 > Ancestors: MonticelloConfigurations-dtl.131 > > Fix updating from streams other than the default. For example: > > MCMcmUpdater > updateFromRepository: 'http://www.squeaksource.com/OSProcess' > baseName: 'update' > I have put three updates into the inbox (MonticelloConfigurations-dtl.131, MonticelloConfigurations-dtl.132, MonticelloConfigurations-dtl.133). Collectively, these are intended to preserve the existing behavior of the update stream for the 'update' and 'update.spur' update streams, while also allowing a package such as OSProcess or VMMaker to have an update stream independent of main (spur versus non-spur) update stream. It should also support more than one update stream in a repository, so for example VMMaker can have its existing 'update' stream, and a parallel 'update.oscog' stream could be added for the Cog/Spur development. This is important for the case of a SqueakMap "(head)" release that uses an update stream to load the latest version of a package, and which must work properly for Spur. I would appreciate a second set of eyes on these changes before I move them to trunk. If no objections I will move them to trunk some time this week. Dave From johnmci at smalltalkconsulting.com Mon May 11 01:41:33 2015 From: johnmci at smalltalkconsulting.com (John McIntosh) Date: Mon May 11 01:41:37 2015 Subject: [squeak-dev] Re: Pending OS-X Cocoa Squeak VM build In-Reply-To: References: Message-ID: Earlier today I pushed some updates to the Cog branch to enable you to compile the SqueakPureObjcCog found in build.macos64x64/squeak.stack.spur/ Right now it seems to be confused by "DateAndTime milliSecondsSinceMidnight" and hangs there. So just tap cmd-'.' to nuke the first call and show the screen. If someone can compile it and figure out what is broken that would be helpful. At the moment the other helper here is running a toolset a decade old and that won't compile the source, You need a current xCode or at least one that is 10.7 or better. On Thu, May 7, 2015 at 11:42 AM, John McIntosh < johnmci@smalltalkconsulting.com> wrote: > Morning. > > I've taken some time to integrate various Pharo and Pyonkee changes into > the Squeak OS-X and iOS cocoa source tree, along with converting the code > base to ARC and modern Obj-C. > > Earlier today I ran a Squeak4.5-13680 32bit image on a 64bit client > 3488 run, 3421 passes, 23 expected failures, 43 failures, 0 errors, 1 > unexpected passes > > However I need some folks to step forward and validate the results, > document what might be broken, look for behaviour anomalies, and refine > exactly what plugins are needed in the base system. > > I also need someone to try this on a 32bit host with 32bit image, and with > a current 64bit image (which I don't have) on a 64bit host. > > Drop me a note and I"ll forward a link to a binary for testing. > > Shortly I will be integrating these changes into the Cog branch and create > an XCode project for building a 64/64 Cog/etc VM. > > -- > =========================================================================== > John M. McIntosh > https://www.linkedin.com/in/smalltalk > =========================================================================== > -- =========================================================================== John M. McIntosh https://www.linkedin.com/in/smalltalk =========================================================================== -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150510/08f1c712/attachment.htm From commits at source.squeak.org Mon May 11 02:31:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 02:31:10 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.979.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.979.mcz ==================== Summary ==================== Name: Morphic-cmm.979 Author: cmm Time: 10 May 2015, 9:30:17.138 pm UUID: 9fd42360-be4c-4997-88ea-88117e1e4573 Ancestors: Morphic-cmm.978 Give any Morph the ability to conditionally delete if it does not have keyboard focus and use it for the scratch pad because setting up a #keyboardFocusChange handler doesn't work or is not robust enough to ensure it remains discreet. =============== Diff against Morphic-cmm.978 =============== Item was added: + ----- Method: Morph>>deleteUnlessHasFocus (in category 'submorphs-add/remove') ----- + deleteUnlessHasFocus + "Runs on a step timer because we cannot be guaranteed to get focus change events." + (ActiveHand keyboardFocus ~= self and: [ self isInWorld ]) ifTrue: + [ self + stopSteppingSelector: #deleteUnlessHasFocus ; + delete ]! Item was changed: ----- Method: SearchBar>>activate:in: (in category 'accessing') ----- activate: event in: morph + self class useScratchPad - UseScratchPad ifTrue: [ event hand keyboardFocus = self scratchPad ifFalse: [ originatingWidget := event hand keyboardFocus ]. self scratchPad selectAll; openInWorld. + self layoutScratchPad. event hand newKeyboardFocus: self scratchPad ] ifFalse: [ self selection: (1 to: self searchTerm size). event hand newKeyboardFocus: morph textMorph ]! Item was added: + ----- Method: SearchBar>>layoutScratchPad (in category 'private') ----- + layoutScratchPad + | pos width | + World mainDockingBars do: + [ : each | each searchBarMorph ifNotNil: + [ : searchBar | pos := searchBar bottomLeft. + width := searchBar width ] ]. + width ifNil: [ width := 250. pos := World topRight - (width @ 5) ]. + scratchPad + width: width ; + position: pos ; + startStepping: #deleteUnlessHasFocus at: Time millisecondClockValue arguments: nil stepTime: 3000! Item was changed: ----- Method: SearchBar>>scratchPad (in category 'accessing') ----- scratchPad ^ scratchPad ifNil: + [ scratchPad := TextMorph new. - [ | pos width | - World mainDockingBars do: - [ : each | each searchBarMorph ifNotNil: - [ : searchBar | pos := searchBar bottomLeft. width:=searchBar width ] ]. - width ifNil: [ width:=250. pos := World topRight - (width @ 5) ]. - scratchPad := TextMorph new. scratchPad + " on: #keyboardFocusChange send: #removeScratchPad to: self ;" - on: #keyboardFocusChange send: #removeScratchPad to: self ; on: #mouseLeave send: #removeScratchPad to: self ; on: #keyStroke send: #handleScratchPadKey: to: self ; backgroundColor: (BalloonMorph balloonColor alpha: 1.0) ; - width: width ; autoFit: true ; wrapFlag: true ; newContents: '--scratch area--' ; yourself. + self layoutScratchPad. - scratchPad position: pos. Preferences menuAppearance3d ifTrue: [ scratchPad addDropShadow ]. scratchPad ]! From eliot.miranda at gmail.com Mon May 11 03:28:44 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon May 11 03:28:49 2015 Subject: [squeak-dev] New Cog VMs available Message-ID: at http://www.mirandabanda.org/files/Cog/VM/VM.r3332/. CogVM binaries as per VMMaker.oscog-eem.1298/r3332 NewspeakVM: Thread lookup rule through from bytecodes to internalFindNewMethod:. Fix genInnerPrimitiveMirrorNewWithArg:. Class's hash was being accessed twice, reusing variable holding jump instruction. Fix primitiveClass and genPrimitiveClass for mirror case (arg count = 1). Also fix Newspeak primitive table to allow nargs > 0 for genPrimitiveClass. General: Fix a regression in externalInstVar:ofContext:. The head frame pointers must be written back if we're going to map a machince code pc to a bytecode pc in case of code reclamation. Add asserts to the stack page enumerators to check that the head frame pointers have been written back. Fix changeClass: for forwwarded receivers. Use macros for the oop comparisons, avoiding cCoerce:, to get faster simulation and avoid the inliner not inlining in conditionals. Spur: Change computeRefCountToShrinkRT to - compute the ref counts and population in a single pass over the RT - determine the ref count for tenuring based on half the population of remembered objects, /not/ half the size of the RT. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150510/295eb2c2/attachment.htm From Marcel.Taeumel at hpi.de Mon May 11 04:02:35 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Mon May 11 04:18:55 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.979.mcz In-Reply-To: References: Message-ID: <1431316955700-4825619.post@n4.nabble.com> Can you name some other scenarious where this #deleteUnlessHasFocus is useful? Looks very specific and not useful in general. We should not blow up the Morph class more than needed. Maybe you could elaborate a little bit more on that feature. You could subclass TextMorph for this special Scratch-Pad-Feature instead of extending the Morph class. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-979-mcz-tp4825614p4825619.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Mon May 11 04:04:06 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Mon May 11 04:20:25 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: References: Message-ID: <1431317046736-4825620.post@n4.nabble.com> Can you elaborate on that "typing blind" use case? My eyes are always opened when I type. ;-) I just don't look at the keyboard but the screen while typing. Not sure what you mean here. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-977-mcz-tp4825591p4825620.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Mon May 11 04:08:15 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Mon May 11 04:24:38 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.976.mcz In-Reply-To: References: Message-ID: <1431317295143-4825621.post@n4.nabble.com> In the future, we should cleary improve keyboard navigation and how workspaces are used. This scratchpad is a symptom of something inconvenient hidden in the Squeak UI. It compares to global state because we can only have one while we can have multiple, independent workspaces. How do you trigger the search in the scratch pad? Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-976-mcz-tp4825590p4825621.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Das.Linux at gmx.de Mon May 11 06:06:42 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Mon May 11 06:06:47 2015 Subject: [squeak-dev] Re: New Cog VMs available In-Reply-To: References: Message-ID: <17DC8EA5-594F-4F66-BD66-AF73BD01D9A9@gmx.de> ? and updated on the ci. best regards -Tobias On 11.05.2015, at 05:28, Eliot Miranda wrote: > at http://www.mirandabanda.org/files/Cog/VM/VM.r3332/. > > CogVM binaries as per VMMaker.oscog-eem.1298/r3332 > > NewspeakVM: > Thread lookup rule through from bytecodes to internalFindNewMethod:. > > Fix genInnerPrimitiveMirrorNewWithArg:. Class's hash was being accessed twice, > reusing variable holding jump instruction. > > Fix primitiveClass and genPrimitiveClass for mirror case (arg count = 1). Also > fix Newspeak primitive table to allow nargs > 0 for genPrimitiveClass. > > General: > Fix a regression in externalInstVar:ofContext:. The head frame pointers must > be written back if we're going to map a machince code pc to a bytecode pc in > case of code reclamation. Add asserts to the stack page enumerators to check > that the head frame pointers have been written back. > > Fix changeClass: for forwwarded receivers. > > Use macros for the oop comparisons, avoiding cCoerce:, to get faster simulation > and avoid the inliner not inlining in conditionals. > > Spur: > Change computeRefCountToShrinkRT to > - compute the ref counts and population in a single pass over the RT > - determine the ref count for tenuring based on half the population of > remembered objects, /not/ half the size of the RT. From Marcel.Taeumel at hpi.de Mon May 11 09:22:51 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Mon May 11 09:39:12 2015 Subject: [squeak-dev] Re: New Cog VMs available In-Reply-To: <17DC8EA5-594F-4F66-BD66-AF73BD01D9A9@gmx.de> References: <17DC8EA5-594F-4F66-BD66-AF73BD01D9A9@gmx.de> Message-ID: <1431336171092-4825641.post@n4.nabble.com> What's with this? http://forum.world.st/win32-Morphic-event-timeStamp-bug-td4824244.html Best, Marcel -- View this message in context: http://forum.world.st/New-Cog-VMs-available-tp4825617p4825641.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Mon May 11 16:07:20 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:07:21 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.564.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.564.mcz ==================== Summary ==================== Name: Collections.spur-ul.564 Author: eem Time: 7 May 2015, 4:32:26.147 pm UUID: 56879fde-78e5-4496-afc9-f21f693fa9de Ancestors: Collections-ul.564 Collections-ul.564 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Make sure that Array >> #isLiteral won't get into an infinite recursion, even if the receiver has an recursive structure. =============== Diff against Collections-ul.564 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:07:19.234 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:07:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:07:37 2015 Subject: [squeak-dev] The Trunk: Collections.spur-topa.565.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-topa.565.mcz ==================== Summary ==================== Name: Collections.spur-topa.565 Author: eem Time: 7 May 2015, 4:32:28.995 pm UUID: d68a2102-8e4c-42ea-91b5-ae58daed13c5 Ancestors: Collections-topa.565, Collections.spur-ul.564 Collections-topa.565 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 When a stream is created on a collection, it tries to keep using that collection instead of copying, even in the case of mutation of the original collection. The code removed prevented this. =============== Diff against Collections-topa.565 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:07:33.505 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:08:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:08:06 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.566.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.566.mcz ==================== Summary ==================== Name: Collections.spur-nice.566 Author: eem Time: 7 May 2015, 4:32:30.651 pm UUID: 6fc245f6-529e-4b92-b876-79e5e66e92eb Ancestors: Collections-nice.566, Collections.spur-topa.565 Collections-nice.566 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Let NullStream understand protocol for Character writing. =============== Diff against Collections-nice.566 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:08:04.612 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:08:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:08:30 2015 Subject: [squeak-dev] The Trunk: Collections.spur-eem.567.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-eem.567.mcz ==================== Summary ==================== Name: Collections.spur-eem.567 Author: eem Time: 7 May 2015, 4:32:33.243 pm UUID: 35573c79-328a-40e1-be23-05ad06f6a4ec Ancestors: Collections-eem.567, Collections.spur-nice.566 Collections-eem.567 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix ([Read|Write]Stream on:...from:...to:...) contents. The old code would always copy from 1 to the end, not from whatever the from: argument was. =============== Diff against Collections-eem.567 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:08:28.511 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:08:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:08:55 2015 Subject: [squeak-dev] The Trunk: Collections.spur-dtl.568.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-dtl.568.mcz ==================== Summary ==================== Name: Collections.spur-dtl.568 Author: eem Time: 7 May 2015, 4:32:34.904 pm UUID: c6909158-5c11-433b-8a91-daae513b5553 Ancestors: Collections-dtl.568, Collections.spur-eem.567 Collections-dtl.568 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Add a flush to WriteStream>>nextChunkPut: This is a workaround for a bug in the runtime library of some versions of Ubuntu. The symptom is that creation of a class comment for a class that previously had no comment leads to a file size error in the new RemoteStream that points to the class comment. Actual file size and contents of the changes file are not affected by this bug, and the error occurs when reading contents of the changes file immediately following the initial save, Flushing the stream after writing a chunk to the changes file prevents the problem. =============== Diff against Collections-dtl.568 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:08:53.629 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:09:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:09:21 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.569.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.569.mcz ==================== Summary ==================== Name: Collections.spur-nice.569 Author: eem Time: 7 May 2015, 4:32:38.01 pm UUID: fa3a04d2-a3b1-412e-a620-57feb357a9b4 Ancestors: Collections-nice.569, Collections.spur-dtl.568 Collections-nice.569 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Add NullStream>>ensureCr =============== Diff against Collections-nice.569 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:09:18.228 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:09:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:09:51 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.570.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.570.mcz ==================== Summary ==================== Name: Collections.spur-nice.570 Author: eem Time: 7 May 2015, 4:32:39.677 pm UUID: 4dcc2ef8-8fe9-4101-936b-65ca0d2c6239 Ancestors: Collections-nice.570, Collections.spur-nice.569 Collections-nice.570 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Let's optimize a bit LinkedList>>at:ifAbsent: by scanning the list only once, unlike super. =============== Diff against Collections-nice.570 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:09:49.047 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:10:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:10:15 2015 Subject: [squeak-dev] The Trunk: Collections.spur-eem.571.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-eem.571.mcz ==================== Summary ==================== Name: Collections.spur-eem.571 Author: eem Time: 7 May 2015, 4:32:41.339 pm UUID: 5e042b5d-c807-452d-b8af-a0e80a3de879 Ancestors: Collections-eem.571, Collections.spur-nice.570 Collections-eem.571 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Speed up testing different sized strings for equality by adding a size text to String>>#=. Tis speeds up e.g. comparing the first 10,000 ByteString instances to each other by -67%. =============== Diff against Collections-eem.571 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:10:10.698 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:10:40 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:10:43 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.572.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.572.mcz ==================== Summary ==================== Name: Collections.spur-nice.572 Author: eem Time: 7 May 2015, 4:32:43.909 pm UUID: 48c7d930-2930-437b-afc1-0020bc0a2186 Ancestors: Collections-nice.572, Collections.spur-eem.571 Collections-nice.572 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Let asUppercase and asLowercase use the unicode tables for wide strings/characters. Care is also taken to correctly handle characters with east asian encoding, but I'm not sure how healthy is this support in trunk... Remove Character>>basicSqueakToIso which is totally obsolete (does not the right thing) and is not sent. =============== Diff against Collections-nice.572 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:10:32.691 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:10:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:11:01 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.573.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.573.mcz ==================== Summary ==================== Name: Collections.spur-ul.573 Author: eem Time: 7 May 2015, 4:32:45.565 pm UUID: a46867e0-e30c-48c8-b328-fbd8d7fd1330 Ancestors: Collections-ul.573, Collections.spur-nice.572 Collections-ul.573 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Character changes - introduced #encodedCharSet to access the EncodedCharSet of a character - all methods use #encodedCharSet instead of (EncodedCharSet charSetAt: self leadingChar) - #isAlphaNumeric uses the EncodedCharSet class's #isAlphaNumeric: method =============== Diff against Collections-ul.573 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:10:58.672 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:11:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:11:26 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.574.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.574.mcz ==================== Summary ==================== Name: Collections.spur-nice.574 Author: eem Time: 7 May 2015, 4:32:48.151 pm UUID: 06256264-374f-48f7-9aee-c0c9691990fd Ancestors: Collections-nice.574, Collections.spur-ul.573 Collections-nice.574 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Less ascii/binary dance. The sender of nextString doesn't try to force ascii, anymore so the implementor doesn't have to force binary. =============== Diff against Collections-nice.574 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:11:22.965 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:11:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:11:57 2015 Subject: [squeak-dev] The Trunk: Collections.spur-eem.575.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-eem.575.mcz ==================== Summary ==================== Name: Collections.spur-eem.575 Author: eem Time: 7 May 2015, 4:32:49.809 pm UUID: ae2aa70e-d353-4442-9cbe-f0ca7a736074 Ancestors: Collections-eem.575, Collections.spur-nice.574 Collections-eem.575 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Remove obsolete primitive new implementation in Interval class (SequenceableCollection no longer implements new). Use basicNew in from:to:[by:]. Spur has a different implementation of new so easier to delete the bogus one than duplicate Spur's in Interval class. =============== Diff against Collections-eem.575 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:11:53.22 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:12:17 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:12:20 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.576.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.576.mcz ==================== Summary ==================== Name: Collections.spur-nice.576 Author: eem Time: 7 May 2015, 4:32:52.759 pm UUID: e81ebf56-6dbc-4a86-805b-ceea4740b55f Ancestors: Collections-nice.576, Collections.spur-eem.575 Collections-nice.576 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Convert a WriteStream into a ReadStream. Beware, this version is optimized to avoid a copy, but is sharing some state. Thus: s := WriteStream on: String new. self writeSomethingOn: s. self readSomethingFrom: s readStream. is a good replacement for: s := ReadWriteStream on: String new. self writeSomethingOn: s. self readSomethingFrom: s reset But avoid overwriting like this: w := String new writeStream. self writeSomethingOn: w. r := w readStream. self writeSomethingElseOn: w reset. self compare: r to: w readStream. =============== Diff against Collections-nice.576 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:12:12.792 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:12:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:12:46 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.577.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.577.mcz ==================== Summary ==================== Name: Collections.spur-nice.577 Author: eem Time: 7 May 2015, 4:32:54.434 pm UUID: 29e8e563-c4e1-4e1c-8b07-6d369737b922 Ancestors: Collections-nice.577, Collections.spur-nice.576 Collections-nice.577 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Convert Base64MimeConverter implementation from ReadWriteStream to alternate WriteStream/ReadStream. Beware, the main class messages now answer a ReadStream, not a ReadWriteStream. =============== Diff against Collections-nice.577 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:12:37.735 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:13:17 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:13:19 2015 Subject: [squeak-dev] The Trunk: Collections.spur-eem.578.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-eem.578.mcz ==================== Summary ==================== Name: Collections.spur-eem.578 Author: eem Time: 7 May 2015, 4:32:56.119 pm UUID: 5d6079d2-3f8c-4c4a-9a8f-54ba7de7e696 Ancestors: Collections-eem.578, Collections.spur-nice.577 Collections-eem.578 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Implement peekLast in TranscriptStream. Implement WriteStream>>ensureEndsWith: in terms of peekLast. =============== Diff against Collections-eem.578 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:13:14.838 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:13:30 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:13:31 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.579.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.579.mcz ==================== Summary ==================== Name: Collections.spur-nice.579 Author: eem Time: 7 May 2015, 4:32:58.718 pm UUID: 6a8e769a-50aa-4e02-855e-c40917237edd Ancestors: Collections-nice.579, Collections.spur-eem.578 Collections-nice.579 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Implement #peekLast in RWBinaryOrTextStream because it has to care whether isBinary or not. =============== Diff against Collections-nice.579 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:13:29.011 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:14:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:14:07 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.580.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.580.mcz ==================== Summary ==================== Name: Collections.spur-nice.580 Author: eem Time: 7 May 2015, 4:33:00.403 pm UUID: 748b825c-1074-4646-a027-e9824bd1f142 Ancestors: Collections-nice.580, Collections.spur-nice.579 Collections-nice.580 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 peekLast commit and try again... =============== Diff against Collections-nice.580 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:14:04.031 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:14:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:14:47 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.581.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.581.mcz ==================== Summary ==================== Name: Collections.spur-nice.581 Author: eem Time: 7 May 2015, 4:33:03.296 pm UUID: e57e9aaf-c28f-4c4b-ba6f-5731e6225ffc Ancestors: Collections-nice.581, Collections.spur-nice.580 Collections-nice.581 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Remove #padToEndWith: from RWBinaryOrTextStream now that it has been moved up to WriteStream. =============== Diff against Collections-nice.581 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:14:35.861 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:15:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:15:26 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.582.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.582.mcz ==================== Summary ==================== Name: Collections.spur-nice.582 Author: eem Time: 7 May 2015, 4:33:05.144 pm UUID: 144f4740-1b26-454d-bb47-62b3178bd3e9 Ancestors: Collections-nice.582, Collections.spur-nice.581 Collections-nice.582 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Port TAG-SortFunctions of Travis Griggs from Cincom public store - version (11,tgriggs) Note that no collation policy were used for String. The spaceship operator <=> is also required in Kernel-Numbers. See also the blog http://objology.blogspot.fr/2010/11/tag-sortfunctions.html and http://objology.blogspot.fr/2010/11/tag-sortfunctions-redux.html Note about the cost of these sort functions: as shown by this mini-bench on cog, using a Symbol costs a bit more (perform:) than a block activation, and monadic block a bit more than dyadic one because activated twice more, but it seems acceptable to me with regard to the great simplification and expressiveness of code : | collec1 collec2 collec3 | collec1 := (1 to: 200000) collect: [:i | 1000000 atRandom-500000]. collec2 := collec1 copy. collec3 := collec1 copy. { [collec1 sort: [:a :b | a abs < b abs]] timeToRun. [collec2 sort: [:e | e abs] ascending] timeToRun. [collec3 sort: #abs ascending] timeToRun. } #(345 532 912) =============== Diff against Collections-nice.582 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:15:19.66 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:15:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:15:52 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.583.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.583.mcz ==================== Summary ==================== Name: Collections.spur-nice.583 Author: eem Time: 7 May 2015, 4:33:08.531 pm UUID: 1a342859-1e59-4b2e-8567-8821e45a1085 Ancestors: Collections-nice.583, Collections.spur-nice.582 Collections-nice.583 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Also classify these SortFunction support in *Collections rather than *Kernel =============== Diff against Collections-nice.583 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:15:49.344 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:16:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:16:11 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.584.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.584.mcz ==================== Summary ==================== Name: Collections.spur-ul.584 Author: eem Time: 7 May 2015, 4:33:10.461 pm UUID: 9a3466f3-26f9-4f50-944b-1509b4003409 Ancestors: Collections-ul.584, Collections.spur-nice.583 Collections-ul.584 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Character changes: - use the value instance variable instead of #asciiValue where possible - implemented #<= and #>= =============== Diff against Collections-ul.584 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:16:07.971 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:16:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:16:50 2015 Subject: [squeak-dev] The Trunk: Collections.spur-cmm.585.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-cmm.585.mcz ==================== Summary ==================== Name: Collections.spur-cmm.585 Author: eem Time: 7 May 2015, 4:33:12.432 pm UUID: 221d3c7d-56d1-4cb2-8e96-7044e687c1b5 Ancestors: Collections-cmm.585, Collections.spur-ul.584 Collections-cmm.585 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Speed up visiting with #addNewElement:. It provides the common pattern of checking for inclusion, followed by add:, in just one scan, instead of two. =============== Diff against Collections-cmm.585 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:16:44.311 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:16:49 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:16:58 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.586.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.586.mcz ==================== Summary ==================== Name: Collections.spur-ul.586 Author: eem Time: 7 May 2015, 4:33:15.529 pm UUID: 05528383-8834-46f3-a2c1-027a253e96e2 Ancestors: Collections-ul.586, Collections.spur-cmm.585 Collections-ul.586 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Symbol table changes: - ensure that enumerations stay consistent - avoid read-write and write-write race conditions - added a safe #condenseNewSymbols method, which is a replacement for former unsafe methods (#shutDown: and #compactSymbolTable). It's also automatically triggered whenever there are more than 1000 NewSymbols. - deprecated #compactSymbolTable - updated some comments Note that interning many symbols is a bit slower, but thread safety is more important. =============== Diff against Collections-ul.586 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:16:48.516 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:17:37 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:17:38 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.587.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.587.mcz ==================== Summary ==================== Name: Collections.spur-ul.587 Author: eem Time: 7 May 2015, 4:33:17.649 pm UUID: 1a167e98-c34d-45e2-804f-fdc9dc4714de Ancestors: Collections-ul.587, Collections.spur-ul.586 Collections-ul.587 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Optimized Interval >> #sum. =============== Diff against Collections-ul.587 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:17:36.198 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:18:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:18:10 2015 Subject: [squeak-dev] The Trunk: Collections.spur-bf.588.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-bf.588.mcz ==================== Summary ==================== Name: Collections.spur-bf.588 Author: eem Time: 7 May 2015, 4:33:20.914 pm UUID: 9b8f8e5c-138d-44de-82cf-15a933642dab Ancestors: Collections-bf.588, Collections.spur-ul.587 Collections-bf.588 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Restore timestamps lost in assignment conversion. =============== Diff against Collections-bf.588 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:18:05.412 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:18:20 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:18:24 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.589.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.589.mcz ==================== Summary ==================== Name: Collections.spur-mt.589 Author: eem Time: 7 May 2015, 4:33:23.145 pm UUID: 3ed78786-6105-466e-b81a-65222b58e5f9 Ancestors: Collections-mt.589, Collections.spur-bf.588 Collections-mt.589 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 comment added to #concatenation =============== Diff against Collections-mt.589 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:18:18.495 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:18:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:19:00 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.590.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.590.mcz ==================== Summary ==================== Name: Collections.spur-mt.590 Author: eem Time: 7 May 2015, 4:33:25.412 pm UUID: b59d8b48-0532-4ac6-8b95-56feb405d35d Ancestors: Collections-mt.590, Collections.spur-mt.589 Collections-mt.590 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Methods added to easily join split strings. =============== Diff against Collections-mt.590 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:18:56.567 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:19:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:20:02 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.591.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.591.mcz ==================== Summary ==================== Name: Collections.spur-mt.591 Author: eem Time: 7 May 2015, 4:33:28.742 pm UUID: 1366d6ba-3ff0-4675-a1cf-745fbbac62ec Ancestors: Collections-mt.591, Collections.spur-mt.590 Collections-mt.591 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Added #flatten as special case for #concatenation to remove any nesting except for strings. Very simple implementation with streams and recursion but not as efficient as #concatenation. =============== Diff against Collections-mt.591 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:19:43.397 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:19:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:20:10 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.593.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.593.mcz ==================== Summary ==================== Name: Collections.spur-mt.593 Author: eem Time: 7 May 2015, 4:33:34.63 pm UUID: 85eb93f0-5547-4266-81a8-4963dba43ecc Ancestors: Collections-mt.593, Collections.spur-mt.592 Collections-mt.593 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 New ordered dictionary added, which keeps track of the insertion order. =============== Diff against Collections-mt.593 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:19:54.359 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:19:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:20:17 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.592.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.592.mcz ==================== Summary ==================== Name: Collections.spur-mt.592 Author: eem Time: 7 May 2015, 4:33:31.189 pm UUID: f7504993-01b4-4b0e-b673-74a13800d421 Ancestors: Collections-mt.592, Collections.spur-mt.591 Collections-mt.592 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Some nil checks replaced with #notNil because ProtoObject knows it and it is faster (about 15%) =============== Diff against Collections-mt.592 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:19:53.076 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:21:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:21:07 2015 Subject: [squeak-dev] The Trunk: Collections.spur-topa.594.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-topa.594.mcz ==================== Summary ==================== Name: Collections.spur-topa.594 Author: eem Time: 7 May 2015, 4:33:37.336 pm UUID: 30ad2ec3-ae4e-41e7-915a-c7017f766de3 Ancestors: Collections-topa.594, Collections.spur-mt.593 Collections-topa.594 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Add #flattened as alias for #flatten. The former makes it more clear a copy will be returned (cf. #reversed), the latter is more in line with ANSI names (cf. #reverse) and other languages. =============== Diff against Collections-topa.594 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:21:00.494 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:21:42 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:21:46 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.595.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.595.mcz ==================== Summary ==================== Name: Collections.spur-mt.595 Author: eem Time: 7 May 2015, 4:33:41.488 pm UUID: 78b4453d-7d2d-43a2-bed2-ac5f06d9fa71 Ancestors: Collections-mt.595, Collections.spur-topa.594 Collections-mt.595 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Some fixes to the OrderedDictionary implementation and its class comment was updated. =============== Diff against Collections-mt.595 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:21:37.911 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:21:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:21:51 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.596.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.596.mcz ==================== Summary ==================== Name: Collections.spur-mt.596 Author: eem Time: 7 May 2015, 4:33:44.748 pm UUID: ff0fdedd-becf-4f97-9c4a-9e400309392a Ancestors: Collections-mt.596, Collections.spur-mt.595 Collections-mt.596 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 some fixes to OrderedDictionary including copy; small part of the protocol of OrderedCollection adopted (#sort, #first, ...). =============== Diff against Collections-mt.596 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:21:42.18 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:22:32 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:22:33 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.597.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.597.mcz ==================== Summary ==================== Name: Collections.spur-mt.597 Author: eem Time: 7 May 2015, 4:33:49.552 pm UUID: 7f14e67a-19d9-4239-8912-6eca5a8a4eb2 Ancestors: Collections-mt.597, Collections.spur-mt.596 Collections-mt.597 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Removed non-working #first: from OrderedDictionary. Was committed by accident. ^__^ =============== Diff against Collections-mt.597 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:22:28.97 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:23:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:23:05 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.598.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.598.mcz ==================== Summary ==================== Name: Collections.spur-ul.598 Author: eem Time: 7 May 2015, 4:33:54.19 pm UUID: ddc785df-4421-4c4f-b967-0cf87f76a445 Ancestors: Collections-ul.598 Collections-ul.598 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Fix: OrderedCollection >> #asArray returns an Array instead of an instance of the class returned by the class side #arrayType method. - Slightly more efficient OrderedCollection >> #sort:. - Merged Collections-ul.589: - Deprecated Collection class >> #randomForPicking. - Replaced all accesses to RandomForPicking with ThreadSafeRandom value. - WeakKeyDictionary >> associationsDo: ignores associations with GC'd keys. This affects all enumerator methods, and makes overriding #keysDo: unnecessary. - Added a new method SequenceableCollection #>> groupsDo:, which works like #groupsOf:atATimeDo:, but uses the block's argument count as the group size. Depends on Kernel-ul.893 =============== Diff against Collections-ul.598 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:22:56.184 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:23:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:23:08 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.599.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.599.mcz ==================== Summary ==================== Name: Collections.spur-mt.599 Author: eem Time: 7 May 2015, 4:33:59.343 pm UUID: bb658c30-8974-4068-8b98-00c3ccef135e Ancestors: Collections-mt.599, Collections.spur-ul.598 Collections-mt.599 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Implemented "First wins"-strategy wrt. to the order of associations. Allowed for simplifying the code. Order array does only grow to 75% to mitigate the greediness of the Dictionary. =============== Diff against Collections-mt.599 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:23:03.608 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:23:49 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:23:50 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.600.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.600.mcz ==================== Summary ==================== Name: Collections.spur-mt.600 Author: eem Time: 7 May 2015, 4:34:03.514 pm UUID: f907ccdc-d522-4361-b00e-0f68c1d078eb Ancestors: Collections-mt.600, Collections.spur-mt.599 Collections-mt.600 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Copy ranges of elements in OrderedDictionary. =============== Diff against Collections-mt.600 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:23:47.167 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:24:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:24:20 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.602.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.602.mcz ==================== Summary ==================== Name: Collections.spur-mt.602 Author: eem Time: 7 May 2015, 4:34:08.845 pm UUID: 5212aa52-369f-46a4-a6c3-11f96e0ac7a1 Ancestors: Collections-mt.602 Collections-mt.602 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Merged improvements for OrderedDictionary from inbox (ul.601). Fixed problem in (mt.600 version) #copyFrom:to: with memory allocation. Preferred this over ul.601 because it is faster (8 per second vs. 12 per second). d := OrderedDictionary new. 1 to: 1000000 do: [:ea | d at: ea put: nil]. [d copyFrom: 250000 to: 750000] bench. =============== Diff against Collections-mt.602 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:24:13.154 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:24:45 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:24:48 2015 Subject: [squeak-dev] The Trunk: Collections.spur-cmm.603.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-cmm.603.mcz ==================== Summary ==================== Name: Collections.spur-cmm.603 Author: eem Time: 7 May 2015, 4:34:15.424 pm UUID: d16e95b3-b1d0-4985-982f-bfe7185fbbf3 Ancestors: Collections-cmm.603, Collections.spur-mt.602 Collections-cmm.603 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Collection>>#groupBy:having: is already being used for non-Integer groups, and integerDictionary is now slower than a regular Dictionary in Spur. - PositionableStream>>#nextInto:, #next:into:, #nextInto:startingAt:, #next:into:startingAt:, and #readInto:startingAt:count require no services specific to PositionableStream. Move them up to Stream and remove the redundant implementations from various subclasses. - Let WeakArray>>#species be a regular Array instead of its own class, so that WeakArray's can be successfully compared to Arrays with equivalent contents. =============== Diff against Collections-cmm.603 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:24:38.109 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:25:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:25:12 2015 Subject: [squeak-dev] The Trunk: Collections.spur-eem.603.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-eem.603.mcz ==================== Summary ==================== Name: Collections.spur-eem.603 Author: eem Time: 7 May 2015, 4:34:22.267 pm UUID: f19534fa-fe0a-4ed6-afa3-6c0e5f04b7c1 Ancestors: Collections-eem.603, Collections.spur-mt.602 Collections-eem.603 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Three fewer uses of isKindOf: =============== Diff against Collections-eem.603 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:24:58.379 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:25:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:25:26 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.604.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.604.mcz ==================== Summary ==================== Name: Collections.spur-ul.604 Author: eem Time: 7 May 2015, 4:34:36.018 pm UUID: 618de3e0-b90e-499f-9e26-831c77ec988b Ancestors: Collections-ul.604, Collections.spur-eem.603 Collections-ul.604 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Reverted the previous workaround for the class comment saving bug, because it's enough to flush the changes file after saving the class comment. See Kerneul-ul.910 for the actual fix. =============== Diff against Collections-ul.604 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:25:23.681 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:25:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:25:57 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.605.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.605.mcz ==================== Summary ==================== Name: Collections.spur-mt.605 Author: eem Time: 7 May 2015, 4:34:46.478 pm UUID: efcff7ab-b0fe-459f-adf5-ba9ff5c4f4c9 Ancestors: Collections-mt.605, Collections.spur-ul.604 Collections-mt.605 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Support #withBlanksTrimmed in texts. =============== Diff against Collections-mt.605 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:25:54.555 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:26:39 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:26:42 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.606.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.606.mcz ==================== Summary ==================== Name: Collections.spur-ul.606 Author: eem Time: 7 May 2015, 4:34:59.463 pm UUID: 1187cb31-05cd-4ea0-a643-90e103adaf03 Ancestors: Collections-ul.606, Collections.spur-mt.605 Collections-ul.606 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Cache and share #separators and #nonSeparators in CharacterSet (just like #crlf). Remove them on #cleanUp. Implemented CharacterSet class >> #withAll:. Removed #noSeparatorMap, #noSeparators, #separatorMap from String class. Also removed the class variables CSNonSeparators, CSSeparators, and CSLineEnders. All users were rewritten to use CharacterSet's version of these sets. =============== Diff against Collections-ul.606 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:26:31.966 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:27:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:27:11 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.607.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.607.mcz ==================== Summary ==================== Name: Collections.spur-ul.607 Author: eem Time: 7 May 2015, 4:35:09.671 pm UUID: 8b3e7ff7-d955-48cd-87e0-06333f241aad Ancestors: Collections-ul.607, Collections.spur-ul.606 Collections-ul.607 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Simplified CharacterSet class>>separators. Fixed ReadStream >> #nextFloat, when collection is not a ByteString. =============== Diff against Collections-ul.607 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:27:05.626 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:27:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:27:14 2015 Subject: [squeak-dev] The Trunk: Collections.spur-cmm.608.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-cmm.608.mcz ==================== Summary ==================== Name: Collections.spur-cmm.608 Author: eem Time: 7 May 2015, 4:35:20.113 pm UUID: 56c16f31-4fe6-4434-9702-3abea55c3b0e Ancestors: Collections-cmm.608, Collections.spur-ul.607 Collections-cmm.608 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Merged cmm.603. =============== Diff against Collections-cmm.608 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:27:10.708 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:28:01 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:28:05 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.610.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.610.mcz ==================== Summary ==================== Name: Collections.spur-ul.610 Author: eem Time: 7 May 2015, 4:35:30.788 pm UUID: 0924be37-47ac-4835-83c2-abb3c621cad1 Ancestors: Collections-ul.610, Collections.spur-cmm.608 Collections-ul.610 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Slightly faster SequenceableCollection >> #copyUpT* (for ByteString receivers). - SequenceableCollection >> #shuffled belongs to the shuffling category. - Added FormatCharacterSet to String, which will be used by the new implementation of #format: - Removed an unused temporary from String >> #expandMacrosWithArguments: =============== Diff against Collections-ul.610 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:27:58.318 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:28:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:28:30 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.611.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.611.mcz ==================== Summary ==================== Name: Collections.spur-ul.611 Author: eem Time: 7 May 2015, 4:35:35.215 pm UUID: 73ff8cfb-c6cf-4e28-a8b9-0a3a15f6e8f0 Ancestors: Collections-ul.611, Collections.spur-ul.610 Collections-ul.611 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Stricter and faster implementation of String >> #format:. =============== Diff against Collections-ul.611 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:28:22.174 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:28:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:28:57 2015 Subject: [squeak-dev] The Trunk: Collections.spur-bf.612.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-bf.612.mcz ==================== Summary ==================== Name: Collections.spur-bf.612 Author: eem Time: 7 May 2015, 4:35:41.094 pm UUID: b78cb1c8-3b66-4228-af43-7f95bf3c87c4 Ancestors: Collections-bf.612, Collections.spur-ul.611 Collections-bf.612 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Ensure that copyWith/out retains the weak-ness of a weak array. =============== Diff against Collections-bf.612 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:28:50.047 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:29:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:29:27 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.613.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.613.mcz ==================== Summary ==================== Name: Collections.spur-tfel.613 Author: eem Time: 7 May 2015, 4:35:45.07 pm UUID: fd03fae6-2513-4d73-8c98-338c89d9e008 Ancestors: Collections-tfel.613, Collections.spur-bf.612 Collections-tfel.613 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix replaceFrom:to:with:startingAt: for ByteArray if run on a VM without primitive 105 =============== Diff against Collections-tfel.613 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:29:14.747 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From asqueaker at gmail.com Mon May 11 16:29:27 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 11 16:29:36 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.979.mcz In-Reply-To: <1431316955700-4825619.post@n4.nabble.com> References: <1431316955700-4825619.post@n4.nabble.com> Message-ID: On Sun, May 10, 2015 at 11:02 PM, marcel.taeumel wrote: > Can you name some other scenarious where this #deleteUnlessHasFocus is > useful? Looks very specific and not useful in general. Your "results" balloon of the SearchBar should use this too. Any morph anywhere that should go away when it loses focus. Handling #mouseLeave is not sufficient because the mouse is not guaranteed to have ever entered the bounds of the Morph. I use this concept in my Maui interfaces a lot -- hovering over a message invokes the message and presents output panel (with hand not inside its bounds), then I mouse away somewhere else but if I never entered the output, there is no mouseLeave event. A similar case are balloon help, which disappear on a timer. > We should not blow up > the Morph class more than needed. Agree, but I think this is useful in several cases and its just one method.. Best, Chris From commits at source.squeak.org Mon May 11 16:29:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:29:50 2015 Subject: [squeak-dev] The Trunk: Collections.spur-bf.614.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-bf.614.mcz ==================== Summary ==================== Name: Collections.spur-bf.614 Author: eem Time: 7 May 2015, 4:35:50.213 pm UUID: 7a0d20b8-f4e7-4258-9fd7-a8de56ff4ccd Ancestors: Collections-bf.614, Collections.spur-tfel.613 Collections-bf.614 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Revert WeakArray>>species temporarily to see if this fixes testNoObsoleteClasses on the build server =============== Diff against Collections-bf.614 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:29:48.111 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:30:30 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:30:32 2015 Subject: [squeak-dev] The Trunk: Collections.spur-bf.615.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-bf.615.mcz ==================== Summary ==================== Name: Collections.spur-bf.615 Author: eem Time: 7 May 2015, 4:35:53.871 pm UUID: f6ae9a3b-be31-482b-b63b-2910bfe82d10 Ancestors: Collections-bf.615, Collections.spur-bf.614 Collections-bf.615 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Restore WeakArray>>species. It's apparently not the culprit for the obsolete class refs. =============== Diff against Collections-bf.615 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:30:29.671 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From asqueaker at gmail.com Mon May 11 16:30:49 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 11 16:30:51 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: <1431317046736-4825620.post@n4.nabble.com> References: <1431317046736-4825620.post@n4.nabble.com> Message-ID: Transcribing some code from a sheet of paper. You're looking at the paper, not the screen, as you type. In that case you want what you typed to be what you typed.. On Sun, May 10, 2015 at 11:04 PM, marcel.taeumel wrote: > Can you elaborate on that "typing blind" use case? My eyes are always opened > when I type. ;-) I just don't look at the keyboard but the screen while > typing. Not sure what you mean here. > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-977-mcz-tp4825591p4825620.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From commits at source.squeak.org Mon May 11 16:35:51 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:35:54 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.616.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.616.mcz ==================== Summary ==================== Name: Collections.spur-ul.616 Author: eem Time: 7 May 2015, 4:35:58.234 pm UUID: 158590ea-4a40-4bfa-8c8f-d6b44c0947b7 Ancestors: Collections-ul.616, Collections.spur-bf.615 Collections-ul.616 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Optimized Interval >> #sum, OrderedCollection >> #at: and OrderedCollection >> #at:put:. =============== Diff against Collections-ul.616 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:35:47.905 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:36:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:36:07 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.617.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.617.mcz ==================== Summary ==================== Name: Collections.spur-ul.617 Author: eem Time: 7 May 2015, 4:36:01.822 pm UUID: 7083b9ba-7e6d-42f8-aec4-0c0949c8a24e Ancestors: Collections-ul.617, Collections.spur-ul.616 Collections-ul.617 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 LRUCache changes: - added a #reset method, which removes all elements from the cache - replaced the Arrays storing the list of elements with custom classes (LRUCacheHeadNode and LRUCacheNode). - fix: the map variable gets correctly updated, when the cache is full =============== Diff against Collections-ul.617 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:36:04.944 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:36:36 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:36:37 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.618.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.618.mcz ==================== Summary ==================== Name: Collections.spur-ul.618 Author: eem Time: 7 May 2015, 4:36:05.26 pm UUID: e9c8860b-3789-4b5e-8c01-4be0471f1ef0 Ancestors: Collections-ul.618, Collections.spur-ul.617 Collections-ul.618 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Various OrderedCollection changes. Adding: - #addAllFirst: can accept any collection as argument, but uses #reverseDo: if the argument has that method. It's implemented with double dispatch by #addAllFirstTo:. - Simplified and recategorized #at:ifAbsentPut:, but kept the unusual semantics of nil values. - Simplified #addAllLast: a bit, and updated its comment. Removing: - #removeAllSuchThat: stores the read element in a temporary - #removeFirst: and #removeLast: doesn't use #removeFirst and #removeLast anymore. Error handling: - removed the unsent #errorConditionNotSatisfied method - changed #errorNoSuchElement to use the name of the receiver instead of "an ordered collection" - added #errorNotEnoughElements, which is used by #removeFirst: and #removeLast: Other: - implemented #indexOf:startingAt:ifAbsent: for better performance - fixed the comment of #isSortedBy:between:and: =============== Diff against Collections-ul.618 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:36:36.167 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:37:20 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:37:23 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.619.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.619.mcz ==================== Summary ==================== Name: Collections.spur-ul.619 Author: eem Time: 7 May 2015, 4:36:10.224 pm UUID: ca341317-48f7-4db4-ab28-6e742534145c Ancestors: Collections-ul.619, Collections.spur-ul.618 Collections-ul.619 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Reset all LRUCache instances in postscript to force migration to the new internal list format. =============== Diff against Collections-ul.619 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:37:13.904 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:37:45 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:37:47 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.620.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.620.mcz ==================== Summary ==================== Name: Collections.spur-ul.620 Author: eem Time: 7 May 2015, 4:36:13.703 pm UUID: 718aad6a-2796-4139-bfd6-2fb72427eade Ancestors: Collections-ul.620, Collections.spur-ul.619 Collections-ul.620 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Removed the migration code, and obsolete private methods from LRUCache. =============== Diff against Collections-ul.620 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:37:39.499 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:38:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:38:03 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.621.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.621.mcz ==================== Summary ==================== Name: Collections.spur-mt.621 Author: eem Time: 7 May 2015, 4:36:18.461 pm UUID: c71e2710-ff47-4fa9-a12c-0bc514118022 Ancestors: Collections-mt.621, Collections.spur-ul.620 Collections-mt.621 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Convenience method added to String to remove line endings/breaks from a string. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:38:01.986 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:39:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:39:16 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.623.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.623.mcz ==================== Summary ==================== Name: Collections.spur-tfel.623 Author: eem Time: 7 May 2015, 4:36:26.013 pm UUID: 34764d01-789e-4769-85ca-2b25f34d16eb Ancestors: Collections-tfel.623, Collections.spur-nice.622 Collections-tfel.623 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 =============== Diff against Collections-tfel.623 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:39:04.071 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:39:45 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:39:50 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.624.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.624.mcz ==================== Summary ==================== Name: Collections.spur-tfel.624 Author: eem Time: 7 May 2015, 4:47:38.789 pm UUID: 2d27d65e-d662-464d-b3f6-31e224c79668 Ancestors: Collections-tfel.624, Collections.spur-tfel.623 Collections-tfel.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String =============== Diff against Collections-tfel.624 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:39:35.016 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:39:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:39:54 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.622.mcz ==================== Summary ==================== Name: Collections.spur-nice.622 Author: eem Time: 7 May 2015, 4:36:21.696 pm UUID: 9f2047d5-1b5d-4d6b-b865-84117b1b5e49 Ancestors: Collections-nice.622, Collections.spur-mt.621 Collections-nice.622 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 #toBraceStack: is not used for compiling { } for so long that it's really time to get rid of it. Symbol>>numArgs: does not need to copy self into a temp var. =============== Diff against Collections-nice.622 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:39:37.474 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: 'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: 'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: 'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From asqueaker at gmail.com Mon May 11 16:39:55 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 11 16:39:59 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.976.mcz In-Reply-To: <1431317295143-4825621.post@n4.nabble.com> References: <1431317295143-4825621.post@n4.nabble.com> Message-ID: > In the future, we should cleary improve keyboard navigation and how > workspaces are used. Sure, but that has nothing to do with this. > This scratchpad is a symptom of something inconvenient > hidden in the Squeak UI. It compares to global state It is global state but it does not compare to global state in the negative way you are trying to portray. > because we can only > have one Which is exactly how it needs to be for this feature. If you need more than one you should open a workspace. That's not what this is for.. > while we can have multiple, independent workspaces. And, you still can. But those are for totally different use-cases than this, but you already know that from our private discussion. > How do you trigger the search in the scratch pad? Again, this is not a use-case for the scratch pad. Nevertheless, you could type and/or highlight your search term, press Command+H followed by Command+G. From commits at source.squeak.org Mon May 11 16:40:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:40:13 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.624.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.624.mcz ==================== Summary ==================== Name: Collections.spur-ul.624 Author: eem Time: 7 May 2015, 4:51:08.312 pm UUID: c7a36141-5368-4147-9012-dd9e12fee43d Ancestors: Collections-ul.624, Collections.spur-tfel.623 Collections-ul.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. =============== Diff against Collections-ul.624 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:40:08.943 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:41:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:41:09 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.625.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.625.mcz ==================== Summary ==================== Name: Collections.spur-mt.625 Author: eem Time: 7 May 2015, 4:54:29.023 pm UUID: a1c648e8-efdd-4360-bd46-60853b97fb28 Ancestors: Collections-mt.625, Collections.spur-tfel.624 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Speed-up #endsWith: for strings. =============== Diff against Collections-mt.625 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:40:59.141 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:41:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:41:36 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.625.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.625.mcz ==================== Summary ==================== Name: Collections.spur-ul.625 Author: eem Time: 7 May 2015, 4:54:30.794 pm UUID: 4d68c315-eb54-4470-bea9-00101059da1b Ancestors: Collections-ul.625, Collections.spur-ul.624 Collections-ul.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. =============== Diff against Collections-ul.625 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:41:25.039 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:41:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:41:50 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.626.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.626.mcz ==================== Summary ==================== Name: Collections.spur-mt.626 Author: eem Time: 7 May 2015, 4:54:32.935 pm UUID: 22f10fab-7965-4bf0-9d28-e8434824c9ef Ancestors: Collections-mt.626, Collections.spur-mt.625 Collections-mt.626 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. =============== Diff against Collections-mt.626 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:41:48.141 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(CharacterTable) a M...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:42:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:42:28 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.627.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.627.mcz ==================== Summary ==================== Name: Collections.spur-ul.627 Author: eem Time: 7 May 2015, 4:54:34.642 pm UUID: 3515592b-0b8b-4304-b21f-eb04607f4538 Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. =============== Diff against Collections-ul.627 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:42:25.579 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:43:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:43:07 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.628.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.628.mcz ==================== Summary ==================== Name: Collections.spur-ul.628 Author: eem Time: 7 May 2015, 4:54:36.343 pm UUID: 678cf901-1058-49b5-a0d2-063749459128 Ancestors: Collections-ul.628, Collections.spur-ul.627 Collections-ul.628 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Merged Collections-ul.625. =============== Diff against Collections-ul.628 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:43:04.207 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:43:42 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:43:45 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.629.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.629.mcz ==================== Summary ==================== Name: Collections.spur-mt.629 Author: eem Time: 7 May 2015, 4:54:38.45 pm UUID: a63e8a11-0208-41ea-b952-0f2bd0f56228 Ancestors: Collections-mt.629, Collections.spur-ul.628 Collections-mt.629 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... =============== Diff against Collections-mt.629 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:43:37.923 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:43:42 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:43:52 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.630.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.630.mcz ==================== Summary ==================== Name: Collections.spur-mt.630 Author: eem Time: 7 May 2015, 4:54:40.185 pm UUID: 1e01643d-bb2f-4218-b242-76abc0906fd2 Ancestors: Collections-mt.630, Collections.spur-mt.629 Collections-mt.630 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 HTML escaping added to html read/writer =============== Diff against Collections-mt.630 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:43:41.698 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:44:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:44:46 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.631.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.631.mcz ==================== Summary ==================== Name: Collections.spur-mt.631 Author: eem Time: 7 May 2015, 4:54:41.917 pm UUID: 7cb6cc3d-7542-48e9-8008-ba775f8ac79a Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 HtmlReadWriter: support for comments added, list of ignored tags added =============== Diff against Collections-mt.631 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:44:37.044 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:44:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:44:53 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.632.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.632.mcz ==================== Summary ==================== Name: Collections.spur-ul.632 Author: eem Time: 7 May 2015, 4:54:44.209 pm UUID: 85499dde-43c2-4b15-b757-e8320927ddf9 Ancestors: Collections-ul.632, Collections.spur-mt.631 Collections-ul.632 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Removed MutexForPicking and RandomForPicking from Collection along with the methods referencing them, because the accessor methods were private, and they were only intended to be used for shuffling. Separated #groupBy: from #groupBy:having:. =============== Diff against Collections-ul.632 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:44:43.351 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:45:30 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:45:33 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.633.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.633.mcz ==================== Summary ==================== Name: Collections.spur-ul.633 Author: eem Time: 7 May 2015, 4:54:46.185 pm UUID: 72b1f6a8-c667-4c68-b237-9f43eeaa2f37 Ancestors: Collections-ul.633, Collections.spur-ul.632 Collections-ul.633 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Don't try to use Character's ClassificationTable when the new class variables are not initialized properly. This is a possible workaround to fix the Spur bootstrap. =============== Diff against Collections-ul.633 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:45:28.782 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:46:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:46:14 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.634.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.634.mcz ==================== Summary ==================== Name: Collections.spur-ul.634 Author: eem Time: 7 May 2015, 4:54:47.969 pm UUID: 777ef210-4137-4ab2-a28e-4e842b0ac7ef Ancestors: Collections-ul.634, Collections.spur-ul.633 Collections-ul.634 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Revert the workaround from Collections-ul.633. =============== Diff against Collections-ul.634 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 11 May 2015 4:46:09.368 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Mon May 11 16:46:19 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:46:22 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.287.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.287.mcz ==================== Summary ==================== Name: Compiler.spur-eem.287 Author: eem Time: 7 May 2015, 5:02:33.408 pm UUID: 2a3d764b-4ebe-4890-9893-b5ab2f6830a0 Ancestors: Compiler-eem.287 Compiler-eem.287 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Quick methods may need schematic temps too... =============== Diff against Compiler-eem.287 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:46:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:46:42 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.288.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.288.mcz ==================== Summary ==================== Name: Compiler.spur-eem.288 Author: eem Time: 7 May 2015, 5:02:35.315 pm UUID: 038116a1-9e95-4654-b1ac-d634dc0bf086 Ancestors: Compiler-eem.288, Compiler.spur-eem.287 Compiler-eem.288 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Provide support for fixing ContextPart>>#quickSend:to:with:super: =============== Diff against Compiler-eem.288 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:47:04 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:47:06 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.289.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.289.mcz ==================== Summary ==================== Name: Compiler.spur-eem.289 Author: eem Time: 7 May 2015, 5:02:37.645 pm UUID: 2a528bc6-b267-431b-9395-39508af1620b Ancestors: Compiler-eem.289, Compiler.spur-eem.288 Compiler-eem.289 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix doits in the codePane of a debugger opened from another debugger. e.g. before this fix 1. debug 3+4. 2. in code pane of debugger #1 debug 4+5 3. in code pane of debugger #2 debug 5+6, boom. The bug was that when the encoder creates temp names for temp vars in the debugged context, which it does by creating messages to DoItIn:'s argument 'ThisContext', if this is a level 3 debug, then the original expression would have a temp var called 'ThisContext' already and that would overwrite the 'ThisContext' argument for this level with a message send, and boom. The fix is merely to filter-out these temps and hence never overwrite DoItIn:'s 'ThisContext' argument in the scope table. =============== Diff against Compiler-eem.289 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:47:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:47:34 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.290.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.290.mcz ==================== Summary ==================== Name: Compiler.spur-eem.290 Author: eem Time: 7 May 2015, 5:02:40.261 pm UUID: a186f51b-c74d-4f0a-be5c-0b72bf817794 Ancestors: Compiler-eem.290, Compiler.spur-eem.289 Compiler-eem.290 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Define the other extension acessor, the one that locates extensions before an extended bytecode. Tighten up the comment on the one that accesses the extension bytecodes themselves. =============== Diff against Compiler-eem.290 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:48:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:48:11 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.291.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.291.mcz ==================== Summary ==================== Name: Compiler.spur-eem.291 Author: eem Time: 7 May 2015, 5:02:42.583 pm UUID: 5090cbae-6fca-468c-af67-34df6a796d96 Ancestors: Compiler-eem.291, Compiler.spur-eem.290 Compiler-eem.291 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 More relevant and neater primitive method decompilation with VMMaker loaded. =============== Diff against Compiler-eem.291 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:48:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:48:24 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-topa.292.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-topa.292.mcz ==================== Summary ==================== Name: Compiler.spur-topa.292 Author: eem Time: 7 May 2015, 5:02:44.863 pm UUID: b930d8c8-e2de-4c3b-ba3b-db8fdb227469 Ancestors: Compiler-topa.292, Compiler.spur-eem.291 Compiler-topa.292 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix super-send DoIts in the debugger. =============== Diff against Compiler-topa.292 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:48:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:48:47 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-bf.293.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-bf.293.mcz ==================== Summary ==================== Name: Compiler.spur-bf.293 Author: eem Time: 7 May 2015, 5:02:47.232 pm UUID: 3ad66d71-2167-4fcc-845b-293c049c27e8 Ancestors: Compiler-bf.293, Compiler.spur-topa.292 Compiler-bf.293 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix deoptimization of ifNil: etc. =============== Diff against Compiler-bf.293 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:49:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:49:15 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-bf.294.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-bf.294.mcz ==================== Summary ==================== Name: Compiler.spur-bf.294 Author: eem Time: 7 May 2015, 5:02:49.55 pm UUID: 8f0efdd0-0b38-4e3e-9ea3-8774962bac26 Ancestors: Compiler-bf.294, Compiler.spur-bf.293 Compiler-bf.294 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Accidentally changed method category. =============== Diff against Compiler-bf.294 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:49:37 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:49:38 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-topa.295.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-topa.295.mcz ==================== Summary ==================== Name: Compiler.spur-topa.295 Author: eem Time: 7 May 2015, 5:02:51.883 pm UUID: ec7871f8-f7f7-4401-b6ee-7491a66b730d Ancestors: Compiler-topa.295, Compiler.spur-bf.294 Compiler-topa.295 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix underscore message names when the #parseSelector: api of Parser is used and, hence, no encoder is available. =============== Diff against Compiler-topa.295 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:50:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:50:14 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-topa.296.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-topa.296.mcz ==================== Summary ==================== Name: Compiler.spur-topa.296 Author: eem Time: 7 May 2015, 5:02:54.488 pm UUID: 68589ec4-f9a6-48fb-8fee-b61d39634947 Ancestors: Compiler-topa.296, Compiler.spur-topa.295 Compiler-topa.296 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 initially, the encoder is self, but does not know about the classEncoding. Guard this, too =============== Diff against Compiler-topa.296 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 16:50:23 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 16:50:24 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-cmm.297.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-cmm.297.mcz ==================== Summary ==================== Name: Compiler.spur-cmm.297 Author: eem Time: 7 May 2015, 5:02:56.827 pm UUID: 65606d5f-9a78-4210-abfd-faebb995ef76 Ancestors: Compiler-cmm.297, Compiler.spur-topa.296 Compiler-cmm.297 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 DoIt evaluation in the debugger needs to be from the selected Context's methodClass, not the receiver's class so that "super" will refer to the correct class. =============== Diff against Compiler-cmm.297 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Mon May 11 17:53:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:53:25 2015 Subject: [squeak-dev] The Trunk: System.spur-dtl.666.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-dtl.666.mcz ==================== Summary ==================== Name: System.spur-dtl.666 Author: eem Time: 7 May 2015, 5:03:01.419 pm UUID: 241a125d-56d8-47db-aafa-1955c1f30044 Ancestors: System-dtl.666 System-dtl.666 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Sending basicNew to CompiledMethod may crash the VM, so don't do that. =============== Diff against System-dtl.666 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now. - timestamp instVarNamed: #nanos put: 0. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:54:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:54:06 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.667.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.667.mcz ==================== Summary ==================== Name: System.spur-cmm.667 Author: eem Time: 7 May 2015, 5:03:05.862 pm UUID: 3d4dcc23-727b-4051-a7a0-ffdef154a4df Ancestors: System-cmm.667, System.spur-dtl.666 System-cmm.667 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Added method to get a valid MethodReference from a stale, invalid one. =============== Diff against System-cmm.667 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now. - timestamp instVarNamed: #nanos put: 0. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:54:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:54:45 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.668.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.668.mcz ==================== Summary ==================== Name: System.spur-cmm.668 Author: eem Time: 7 May 2015, 5:03:10.22 pm UUID: de74b4cb-5976-45a5-936f-cb53807c1263 Ancestors: System-cmm.668, System.spur-cmm.667 System-cmm.668 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Fix to SmalltalkImage>>#sourcesName allows appending the changes to the sources file (via Levente's SmalltalkImage>>#appendChangesTo:) to work. - Added #moveChanges as this should become a normal part of the release process. - Some categorizations. =============== Diff against System-cmm.668 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now. - timestamp instVarNamed: #nanos put: 0. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:55:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:55:10 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.669.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.669.mcz ==================== Summary ==================== Name: System.spur-cmm.669 Author: eem Time: 7 May 2015, 5:03:15.355 pm UUID: bc4cc420-edef-4ab9-809c-3a931958f027 Ancestors: System-cmm.669, System.spur-cmm.668 System-cmm.669 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 #moveChanges should prompt for the name of the condensed sources. =============== Diff against System-cmm.669 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now. - timestamp instVarNamed: #nanos put: 0. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:55:53 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:55:55 2015 Subject: [squeak-dev] The Trunk: System.spur-cwp.670.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cwp.670.mcz ==================== Summary ==================== Name: System.spur-cwp.670 Author: eem Time: 7 May 2015, 5:03:20.392 pm UUID: e197af29-608b-4ce6-b53f-947e767206d1 Ancestors: System-cwp.670, System.spur-cmm.669 System-cwp.670 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Rename EnvironmentRequest to CurrentEnvironment, use the new "Environment current" mechanism where appropriate. =============== Diff against System-cwp.670 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now. - timestamp instVarNamed: #nanos put: 0. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:56:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:57:02 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.671.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.671.mcz ==================== Summary ==================== Name: System.spur-eem.671 Author: eem Time: 7 May 2015, 5:03:24.808 pm UUID: ace17ff8-0797-4d9e-a4a8-5d64dfdf5453 Ancestors: System-eem.671, System.spur-cwp.670 System-eem.671 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix allStoresInto:from: for pool variables and hence fix browsing assignments... to a pool variable in classes that use the pool. =============== Diff against System-eem.671 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now. - timestamp instVarNamed: #nanos put: 0. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:57:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:57:22 2015 Subject: [squeak-dev] The Trunk: System.spur-dtl.672.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-dtl.672.mcz ==================== Summary ==================== Name: System.spur-dtl.672 Author: eem Time: 7 May 2015, 5:03:30.258 pm UUID: ffa75e57-573c-410c-8c48-71f394f3544a Ancestors: System-dtl.672, System.spur-eem.671 System-dtl.672 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Provide DateAndTme>>floor so that ObjectHistoryMark does not need to use instVarAt:put: to obtain a time stamp with whole seconds. This protects for future changes to DateAndTime that may not rely on an instance variable named #nanos. =============== Diff against System-dtl.672 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:58:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:58:29 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.673.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.673.mcz ==================== Summary ==================== Name: System.spur-nice.673 Author: eem Time: 7 May 2015, 5:03:35.185 pm UUID: 7c942c65-754c-4159-944a-3131d9b95ec8 Ancestors: System-nice.673, System.spur-dtl.672 System-nice.673 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Continue to disentangle the nest of vipers, one knot at a time. Replace usage of compressedMIMEEncodedStream, because - we do not need a ReadWriteStream (such requirement should be so rare) - we do not even need a ReadStream - we just need a String So let's use a String =============== Diff against System-nice.673 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:58:52 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:58:55 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.674.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.674.mcz ==================== Summary ==================== Name: System.spur-nice.674 Author: eem Time: 7 May 2015, 5:03:39.584 pm UUID: 98a45de4-8dde-4126-a5a8-a8e985346d71 Ancestors: System-nice.674, System.spur-nice.673 System-nice.674 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Remove SmartRefStream class>>streamedRepresentationOf: which is essentially the same as super. The sole difference is that it tries to close the RWBinaryOrTextStream, but this is a no-op... =============== Diff against System-nice.674 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 17:59:17 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 17:59:21 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.675.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.675.mcz ==================== Summary ==================== Name: System.spur-nice.675 Author: eem Time: 7 May 2015, 5:03:44.768 pm UUID: 84a04f5b-856a-4421-9ef6-71ecd965ac98 Ancestors: System-nice.675, System.spur-nice.674 System-nice.675 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Remove a bit of ascii/binary dance. This is possible - in CodeLoader because ByteArray now understands unzipped - in DataStream>>readString, because nextString will turn stream to binary right after we asked for ascii... - in SmartRefStream>>appendClassDefns because we can forward the job to an asciiStream. Beware, this last part was not WideString friendly, and still isn't really. We should better use something like UTF8 but it's not a local change - we'll see later... =============== Diff against System-nice.675 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:00:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:00:07 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.676.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.676.mcz ==================== Summary ==================== Name: System.spur-eem.676 Author: eem Time: 7 May 2015, 5:03:49.764 pm UUID: 3efe25c0-7ef6-428a-ae8f-87fb34622bf5 Ancestors: System-eem.676, System.spur-nice.675 System-eem.676 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix vmStatisticsReportString for Spur. Provide Smalltalk vm isRunningSpur. Improve isRunningCogit & isRunningCog Extend the comment in vmParameterAt: =============== Diff against System-eem.676 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:00:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:00:45 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.677.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.677.mcz ==================== Summary ==================== Name: System.spur-kfr.677 Author: eem Time: 7 May 2015, 5:03:54.18 pm UUID: 0d342798-3936-4f58-87b1-6be9ca713913 Ancestors: System-kfr.677, System.spur-eem.676 System-kfr.677 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Don't put collapsed windows behind the docking bar. =============== Diff against System-kfr.677 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:01:22 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:01:24 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.678.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.678.mcz ==================== Summary ==================== Name: System.spur-kfr.678 Author: eem Time: 7 May 2015, 5:03:59.472 pm UUID: f73bddd7-e560-4dc5-b474-778f4a6c3eb7 Ancestors: System-kfr.678, System.spur-kfr.677 System-kfr.678 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 When collapsing windows pay attention to the height of the docking bar =============== Diff against System-kfr.678 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:02:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:02:03 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.679.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.679.mcz ==================== Summary ==================== Name: System.spur-kfr.679 Author: eem Time: 7 May 2015, 5:04:04.465 pm UUID: 42eb2277-b248-4fd4-a385-e1b108c268ce Ancestors: System-kfr.679, System.spur-kfr.678 System-kfr.679 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Utilities class>>commandKeyMappings is now a help topic. This menthod is removed to avoid dupication Utilities class>>openCommandKeyHelp opens a HelpBrowser =============== Diff against System-kfr.679 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:02:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:02:38 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.680.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.680.mcz ==================== Summary ==================== Name: System.spur-nice.680 Author: eem Time: 7 May 2015, 5:04:08.773 pm UUID: f835c572-84db-47ea-affd-3e7f182afadb Ancestors: System-nice.680, System.spur-kfr.679 System-nice.680 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 RWStream Shoot them up part 4: How to drop an image without a RWBinaryOrTextStream. I feel like applying a balm on chicken pox one by one. There are a lot of them, my image is crippled, and it's itching considerably! =============== Diff against System-nice.680 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:03:22 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:03:24 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.681.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.681.mcz ==================== Summary ==================== Name: System.spur-nice.681 Author: eem Time: 7 May 2015, 5:04:14.116 pm UUID: 6f36a8f2-c5af-42af-96bc-b28e5ea3074e Ancestors: System-nice.681, System.spur-nice.680 System-nice.681 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Remove one useless send of reset. By the way, this is twice the same method... TODO remove the InternalTranslator version. =============== Diff against System-nice.681 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:04:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:04:12 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.682.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.682.mcz ==================== Summary ==================== Name: System.spur-nice.682 Author: eem Time: 7 May 2015, 5:04:19.126 pm UUID: db7deb11-f7d0-4d29-8945-db6443018714 Ancestors: System-nice.682, System.spur-nice.681 System-nice.682 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Use peekLast in ReferenceStream rather than skip: -1; next. This is now going to work on a simple WriteStream (no ReadWriteStream requirement). Note: I don't understand what was a uggly workaround, the fact to peekLast, or (byteStream skip: 0)? If it's (byteStream skip: 0), I don't know what it works around, and I just cross fingers... The sole reference google got me was too far and too light http://st-www.cs.illinois.edu/squeak/Squeak2.0/updates/152hide&show-LG-tk.cs =============== Diff against System-nice.682 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:04:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:05:00 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.683.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.683.mcz ==================== Summary ==================== Name: System.spur-nice.683 Author: eem Time: 7 May 2015, 5:04:24.219 pm UUID: 0722bc99-a471-4bf7-9985-81a92bdc7aa8 Ancestors: System-nice.683, System.spur-nice.682 System-nice.683 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Let a WriteStream be smart by moving the capability to fileOutClass:andObject: up from ReadWriteStream. Note: I really don't believe that any of these messages belongs to a Stream hierarchy. But disentangling the stream mess means loosen more than one knot, and I don't want the operation to look like conjuring, we need a careful trace for understanding, dissecting and reverting the potentially lost features, so one change at a time. =============== Diff against System-nice.683 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:05:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:05:13 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.684.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.684.mcz ==================== Summary ==================== Name: System.spur-eem.684 Author: eem Time: 7 May 2015, 5:04:28.595 pm UUID: 78e1ca83-1378-42fc-b627-b1864a1a5f8a Ancestors: System-eem.684, System.spur-nice.683 System-eem.684 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix mis-categorization =============== Diff against System-eem.684 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:06:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:06:10 2015 Subject: [squeak-dev] The Trunk: System.spur-dtl.685.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-dtl.685.mcz ==================== Summary ==================== Name: System.spur-dtl.685 Author: eem Time: 7 May 2015, 5:04:33.679 pm UUID: a5004ee7-8bd6-44b0-ac10-3f21b2b9f87c Ancestors: System-dtl.685, System.spur-eem.684 System-dtl.685 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Smalltalk isRunningCog should answer false for an interpreter VM =============== Diff against System-dtl.685 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:06:31 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:06:32 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.688.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.688.mcz ==================== Summary ==================== Name: System.spur-ul.688 Author: eem Time: 7 May 2015, 5:04:38.748 pm UUID: 464046be-c71c-4969-b36f-f8387fe206ee Ancestors: System-ul.688, System.spur-dtl.685 System-ul.688 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Replaced ExternalSemaphoreTable with ExternalObjectTable to provide faster registration, and give better support to the current users of external objects. Notable changes: - the table is a separate object instead of a few class side methods - the whole API can be found in SmalltalkImage in the external objects category - #newExternalSemaphore, #newExternalSemaphoreDo: and #newExternalSemaphores: provide fast and easy creation and registration of Semaphores - #unregisterExternalObjects: can unregister multiple objects faster - #externalObjects will return a copy of the externalObjectsArray - better scalability - the maxExternalSemaphores VM parameter will be incremented as the externalObjectsArray grows =============== Diff against System-ul.688 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:07:16 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:07:18 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.689.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.689.mcz ==================== Summary ==================== Name: System.spur-cmm.689 Author: eem Time: 7 May 2015, 5:04:43.105 pm UUID: 5cb56397-0e6f-4262-b025-4e0f0aef40ba Ancestors: System-cmm.689, System.spur-ul.688 System-cmm.689 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Populate all LocaleID's 'country's. =============== Diff against System-cmm.689 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:07:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:08:02 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.690.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.690.mcz ==================== Summary ==================== Name: System.spur-cmm.690 Author: eem Time: 7 May 2015, 5:04:48.254 pm UUID: 989441e2-d124-4144-ad9c-6ae66f4b1975 Ancestors: System-cmm.690, System.spur-cmm.689 System-cmm.690 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 resetKnownLocales too after setting LocaleID's country's. =============== Diff against System-cmm.690 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:08:47 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:08:48 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.691.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.691.mcz ==================== Summary ==================== Name: System.spur-eem.691 Author: eem Time: 7 May 2015, 5:04:53.745 pm UUID: 6f78b212-7c69-4de3-8cfd-48d8756429a2 Ancestors: System-eem.691, System.spur-cmm.690 System-eem.691 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Add SmallInteger to the front of the start-up list defined by initializeStartUpList. =============== Diff against System-eem.691 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:09:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:09:32 2015 Subject: [squeak-dev] The Trunk: System.spur-bf.692.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-bf.692.mcz ==================== Summary ==================== Name: System.spur-bf.692 Author: eem Time: 7 May 2015, 5:04:58.134 pm UUID: 83c34a3d-849f-46d9-96d7-6052bfa36af6 Ancestors: System-bf.692, System.spur-eem.691 System-bf.692 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Restore timestamps lost in assignment conversion. =============== Diff against System-bf.692 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:10:10 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:10:13 2015 Subject: [squeak-dev] The Trunk: System.spur-dtl.693.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-dtl.693.mcz ==================== Summary ==================== Name: System.spur-dtl.693 Author: eem Time: 7 May 2015, 5:05:03.14 pm UUID: f994728e-0934-4069-834c-173c0cdcd2a3 Ancestors: System-dtl.693, System.spur-bf.692 System-dtl.693 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 VM statistics array size varies for different VM implementations =============== Diff against System-dtl.693 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:10:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:10:32 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.693.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.693.mcz ==================== Summary ==================== Name: System.spur-kfr.693 Author: eem Time: 7 May 2015, 5:05:08.468 pm UUID: b112017b-9737-477b-a442-8731bb771364 Ancestors: System-kfr.693, System.spur-bf.692 System-kfr.693 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 empty log message =============== Diff against System-kfr.693 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:11:19 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:11:23 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.694.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.694.mcz ==================== Summary ==================== Name: System.spur-cmm.694 Author: eem Time: 7 May 2015, 5:05:12.841 pm UUID: 103d5916-9733-40e9-934d-c6ca935e86c6 Ancestors: System-cmm.694, System.spur-dtl.693 System-cmm.694 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - #flush stdout and stderr after writing error information to them. - After that, if the exception is resumable (i.e. a Warning), resume it. Except if its a MessageNotUnderstood -- that is not an error you want to resume in a headless environment. =============== Diff against System-cmm.694 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:12:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:12:14 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.694.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.694.mcz ==================== Summary ==================== Name: System.spur-kfr.694 Author: eem Time: 7 May 2015, 5:05:17.903 pm UUID: 18492c86-aa3a-4b73-a553-32e98482a03b Ancestors: System-kfr.694, System.spur-kfr.693 System-kfr.694 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 empty log message =============== Diff against System-kfr.694 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:12:37 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:12:43 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.695.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.695.mcz ==================== Summary ==================== Name: System.spur-kfr.695 Author: eem Time: 7 May 2015, 5:05:22.96 pm UUID: c7fe1814-6b51-4675-8164-c3bbda7840b4 Ancestors: System-kfr.695, System.spur-kfr.694 System-kfr.695 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix a image lock up with preference look up =============== Diff against System-kfr.695 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:13:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:13:13 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.696.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.696.mcz ==================== Summary ==================== Name: System.spur-cmm.696 Author: eem Time: 7 May 2015, 5:05:27.31 pm UUID: 5a06843f-ebc3-43e5-bea4-b485d3769f4a Ancestors: System-cmm.696, System.spur-kfr.695 System-cmm.696 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Remove the crazy check for MessageNotUnderstood in Smalltalk #run:.. Headless mode should always exit on any Error. - In fact, even when not in headless mode, we don't need to halt but simply #pass the Error to the default handler for Errors do what it does, whether that's popping a debugger which could be resumed (if the Error isResumable) or something else. =============== Diff against System-cmm.696 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:13:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:14:01 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.697.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.697.mcz ==================== Summary ==================== Name: System.spur-mt.697 Author: eem Time: 7 May 2015, 5:05:32.761 pm UUID: fb86bae3-207d-4f80-8f47-5ae8cf89ab5c Ancestors: System-mt.697, System.spur-cmm.696 System-mt.697 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Let message tally ignore #home but just use #sender to handle block closures correctly. =============== Diff against System-mt.697 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:15:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:15:10 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.698.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.698.mcz ==================== Summary ==================== Name: System.spur-eem.698 Author: eem Time: 7 May 2015, 5:05:37.777 pm UUID: f723700b-2cf7-4237-a6fe-b6102ce48d61 Ancestors: System-eem.698, System.spur-mt.697 System-eem.698 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Provide an obsolete method for ObjectHistory that kills the current ObjectHistory's mark process if the class is removed. This allows Spur to easily remove ObjectHistory, which it does not support. =============== Diff against System-eem.698 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:15:19 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:15:21 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.699.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.699.mcz ==================== Summary ==================== Name: System.spur-eem.699 Author: eem Time: 7 May 2015, 5:05:42.162 pm UUID: 16bd99c7-af0e-4699-898c-7f3913bbfec3 Ancestors: System-eem.699, System.spur-eem.698 System-eem.699 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Add block nesting to MessageTally. c.f. AndreasProfiler-eem.10 =============== Diff against System-eem.699 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:16:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:16:10 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.700.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.700.mcz ==================== Summary ==================== Name: System.spur-eem.700 Author: eem Time: 7 May 2015, 5:05:47.379 pm UUID: 376c512c-e319-493d-ace9-22931244fc8d Ancestors: System-eem.700, System.spur-eem.699 System-eem.700 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 MessageTally>>tally:by: should check block nesting. =============== Diff against System-eem.700 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:16:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:16:44 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.701.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.701.mcz ==================== Summary ==================== Name: System.spur-eem.701 Author: eem Time: 7 May 2015, 5:05:52.475 pm UUID: a04988dd-1303-40d6-8a47-779011b1c600 Ancestors: System-eem.701, System.spur-eem.700 System-eem.701 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Invoke super obsolete in ObjectHistory class>>obsolete =============== Diff against System-eem.701 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:17:01 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:17:04 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.702.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.702.mcz ==================== Summary ==================== Name: System.spur-eem.702 Author: eem Time: 7 May 2015, 5:05:56.91 pm UUID: 4513c5a1-f536-4b9f-8c7b-e916a5e38605 Ancestors: System-eem.702, System.spur-eem.701 System-eem.702 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Make DataStream class>>testWith: compare the result if #= doesn't default to #== (or at least doesn't default to Object's#=) =============== Diff against System-eem.702 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:18:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:18:03 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.703.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.703.mcz ==================== Summary ==================== Name: System.spur-eem.703 Author: eem Time: 7 May 2015, 5:06:02.17 pm UUID: b586aff5-92c9-4b8a-80a9-1d30d4926001 Ancestors: System-eem.703, System.spur-eem.702 System-eem.703 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix Homer moment =============== Diff against System-eem.703 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:18:31 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:18:35 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.704.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.704.mcz ==================== Summary ==================== Name: System.spur-topa.704 Author: eem Time: 7 May 2015, 5:06:07.089 pm UUID: e6319209-a0c1-4c45-9c61-a8df9b11336a Ancestors: System-topa.704, System.spur-eem.703 System-topa.704 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Retain scrollBar look now that the pref actually does something (as of Morphic-mt.758) =============== Diff against System-topa.704 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:19:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:19:09 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.705.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.705.mcz ==================== Summary ==================== Name: System.spur-mt.705 Author: eem Time: 7 May 2015, 5:06:11.447 pm UUID: 59a60db7-5da9-4d7c-acb9-3f2eff13b8a5 Ancestors: System-mt.705, System.spur-topa.704 System-mt.705 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Auto-generated method for #gradientMenu removed because of postload-script in Morphic-mt.764. =============== Diff against System-mt.705 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:20:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:20:11 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.706.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.706.mcz ==================== Summary ==================== Name: System.spur-mt.706 Author: eem Time: 7 May 2015, 5:06:16.773 pm UUID: 32f7d226-b517-4385-942c-6e7896205948 Ancestors: System-mt.706, System.spur-mt.705 System-mt.706 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Re-activated possibility to have multiple categories for a single preference. Worked for old-style preferences, now works again for pragma-style preferences. Use #categoryList: instead of #category: in the pragma and provide an array of strings (or symbols). =============== Diff against System-mt.706 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:20:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:20:28 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.707.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.707.mcz ==================== Summary ==================== Name: System.spur-mt.707 Author: eem Time: 7 May 2015, 5:06:21.941 pm UUID: a16a2f71-a8f0-4d38-be80-a19dcd4a9e6c Ancestors: System-mt.707, System.spur-mt.706 System-mt.707 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Old-style preference #roundedMenuCorners removed. See Morphic-mt.766 postload-script. =============== Diff against System-mt.707 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:20:46 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:20:50 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.708.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.708.mcz ==================== Summary ==================== Name: System.spur-eem.708 Author: eem Time: 7 May 2015, 5:06:26.299 pm UUID: db19059c-9190-46a3-ae75-06cec49ff947 Ancestors: System-eem.708, System.spur-mt.707 System-eem.708 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Have BreakpointManager preserve source when adding breakpoints via toggle on entry. =============== Diff against System-eem.708 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:22:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:22:11 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.709.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.709.mcz ==================== Summary ==================== Name: System.spur-eem.709 Author: eem Time: 7 May 2015, 5:06:31.649 pm UUID: b578f643-b7bc-487c-b74e-0a9a8643efdf Ancestors: System-eem.709, System.spur-eem.708 System-eem.709 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix breakpoint source when pragmas follow temporaries. =============== Diff against System-eem.709 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:22:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:22:45 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.710.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.710.mcz ==================== Summary ==================== Name: System.spur-topa.710 Author: eem Time: 7 May 2015, 5:06:36.921 pm UUID: 22e1c1cc-b948-4167-af42-307c8ac3716a Ancestors: System-topa.710, System.spur-eem.709 System-topa.710 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Port the wrapping breakpoint implementation from OB-SUnitintegration. (An addition to BreakPoint, no replacement) =============== Diff against System-topa.710 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:23:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:23:06 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.711.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.711.mcz ==================== Summary ==================== Name: System.spur-cmm.711 Author: eem Time: 7 May 2015, 5:06:41.393 pm UUID: 73ab7eac-d338-4685-949d-5f012e720ca2 Ancestors: System-cmm.711, System.spur-topa.710 System-cmm.711 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Log filed-in code to the changes file. =============== Diff against System-cmm.711 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:24:16 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:24:21 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.712.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.712.mcz ==================== Summary ==================== Name: System.spur-eem.712 Author: eem Time: 7 May 2015, 5:06:46.703 pm UUID: 9c3e05b8-e943-4517-be1a-bcec65751e43 Ancestors: System-eem.712, System.spur-cmm.711 System-eem.712 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Fix allStoresInto: for pool variables. Shared pools are inherited and don't have to be declared in each subclass. =============== Diff against System-eem.712 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:24:22 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:24:30 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.713.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.713.mcz ==================== Summary ==================== Name: System.spur-ul.713 Author: eem Time: 7 May 2015, 5:06:51.877 pm UUID: 834063c2-8747-4b0b-9a66-304b6fc18381 Ancestors: System-ul.713, System.spur-eem.712 System-ul.713 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Use a custom CharacterSet for separators instead of modifying the one in CharacterSet - which may be shared. Cache it for better performance, and get rid of it during cleanUp. =============== Diff against System-ul.713 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:25:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:25:48 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.714.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.714.mcz ==================== Summary ==================== Name: System.spur-ul.714 Author: eem Time: 7 May 2015, 5:06:57.372 pm UUID: 14cd69a5-811c-4256-88fa-53a7a7951e3c Ancestors: System-ul.714, System.spur-ul.713 System-ul.714 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Avoid LargeInteger arithmetic in ThirtyTwoBitRegister>>leftRotateBy:. =============== Diff against System-ul.714 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:25:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:25:57 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.715.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.715.mcz ==================== Summary ==================== Name: System.spur-topa.715 Author: eem Time: 7 May 2015, 5:07:01.797 pm UUID: 6be07029-7c85-4689-982f-c5d77979689e Ancestors: System-topa.715, System.spur-ul.714 System-topa.715 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Make SoundService registeredClasses class-based. Categorize in AppRegistry =============== Diff against System-topa.715 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:27:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:27:04 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.716.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.716.mcz ==================== Summary ==================== Name: System.spur-mt.716 Author: eem Time: 7 May 2015, 5:07:07.032 pm UUID: 5e0933fe-9097-432a-9a7d-c797791362b7 Ancestors: System-mt.716, System.spur-topa.715 System-mt.716 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Refactored window color handling. Added a #normalColor to the specs because I will remove the #duller-hack from SystemWindow and this ensures that users will not be overwhelmed by bright colors. =============== Diff against System-mt.716 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:27:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:27:45 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.717.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.717.mcz ==================== Summary ==================== Name: System.spur-mt.717 Author: eem Time: 7 May 2015, 5:07:12.597 pm UUID: 200be324-9acd-4b81-aaba-46a762cf7e0b Ancestors: System-mt.717, System.spur-mt.716 System-mt.717 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Use general window-update function when changing window colors. =============== Diff against System-mt.717 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:28:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:28:14 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.718.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.718.mcz ==================== Summary ==================== Name: System.spur-topa.718 Author: eem Time: 7 May 2015, 5:07:17.004 pm UUID: dc88cf4f-a5a4-4c84-9fb9-56c03049fee8 Ancestors: System-topa.718, System.spur-mt.717 System-topa.718 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Drop dependencies. For Preferences class>>#restorePreferencesFromDisk, we restore the old version, since right away there is no good way to allow old behavior (loading 'my.prefs'), selecting a custom prefs file, AND not depending on tools. =============== Diff against System-topa.718 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:28:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:28:35 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.719.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.719.mcz ==================== Summary ==================== Name: System.spur-mt.719 Author: eem Time: 7 May 2015, 5:07:22.75 pm UUID: 8d9f5263-d15e-4e26-b7f8-8ec79d407772 Ancestors: System-mt.719, System.spur-topa.718 System-mt.719 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Removed menu-button pref from Preferences because it is now in ScrollBar class. =============== Diff against System-mt.719 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:29:31 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:29:36 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.720.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.720.mcz ==================== Summary ==================== Name: System.spur-ul.720 Author: eem Time: 7 May 2015, 5:07:27.601 pm UUID: c902e39f-a58c-4403-a744-83a7fccd0664 Ancestors: System-ul.720, System.spur-mt.719 System-ul.720 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Added left and right shifts, multiplication, load from register, and comparision operators to ThirtyTwoBitRegister. Also implmenented #hash, and added #asSignedInteger. =============== Diff against System-ul.720 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:29:49 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:29:54 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.721.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.721.mcz ==================== Summary ==================== Name: System.spur-ul.721 Author: eem Time: 7 May 2015, 5:07:32.055 pm UUID: 5a2c1c5a-dec5-4a53-9fb5-7acdc098de50 Ancestors: System-ul.721, System.spur-ul.720 System-ul.721 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Updated the class comment of ThirtyTwoBitRegister. =============== Diff against System-ul.721 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:30:40 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:30:44 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.722.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.722.mcz ==================== Summary ==================== Name: System.spur-mt.722 Author: eem Time: 7 May 2015, 5:07:37.698 pm UUID: 68527acb-0384-4206-aac8-f8f972efc25e Ancestors: System-mt.722, System.spur-ul.721 System-mt.722 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 MVC compatibility fix for the "Do..." menu. =============== Diff against System-mt.722 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:42:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:42:15 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.723.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.723.mcz ==================== Summary ==================== Name: System.spur-ul.723 Author: eem Time: 7 May 2015, 5:07:43.28 pm UUID: 1204482b-1f93-4c4e-844b-9a2195122db9 Ancestors: System-ul.723, System.spur-mt.722 System-ul.723 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Removed the text attributes from ThirtyTwoBitRegister's comment, because source.squeak.org doesn't like them. =============== Diff against System-ul.723 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:43:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:43:04 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.724.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.724.mcz ==================== Summary ==================== Name: System.spur-mt.724 Author: eem Time: 7 May 2015, 5:07:49.835 pm UUID: 43db0f55-0f0b-4de8-8507-89fbb3a17adf Ancestors: System-mt.724, System.spur-ul.723 System-mt.724 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Move check for big displays from SystemWindow to RealEstateManager. Some refactorings in RealEstateManager. =============== Diff against System-mt.724 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:43:52 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:43:54 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.725.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.725.mcz ==================== Summary ==================== Name: System.spur-cmm.725 Author: eem Time: 7 May 2015, 5:07:55.117 pm UUID: 988e46ad-aa9f-4751-aec4-36efedf09bf1 Ancestors: System-cmm.725, System.spur-mt.724 System-cmm.725 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 - Attempting to load preferences is blowing up, fix by restoring the old one-click behavior. - Proper fix for browsing allStoresInto: SomeClassVar from: aClassOrMetaclass, so that all stores occurring in either the instance or class side will be revealed even if the browse was initiated from the class-side. =============== Diff against System-cmm.725 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:44:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:44:45 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.726.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.726.mcz ==================== Summary ==================== Name: System.spur-kfr.726 Author: eem Time: 7 May 2015, 5:08:00.51 pm UUID: b1a14d68-0048-4b3c-9b27-a0fb7abcdf50 Ancestors: System-kfr.726, System.spur-cmm.725 System-kfr.726 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Register fileService for *.pref. Preferences can now be loaded from FileList =============== Diff against System-kfr.726 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:44:41 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:44:55 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.727.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.727.mcz ==================== Summary ==================== Name: System.spur-kfr.727 Author: eem Time: 7 May 2015, 5:08:07.295 pm UUID: bd498d31-7c8b-4796-b4e8-d8daa6051cfd Ancestors: System-kfr.727, System.spur-kfr.726 System-kfr.727 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Missing method for loading preferences =============== Diff against System-kfr.727 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:45:45 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:45:51 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.728.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.728.mcz ==================== Summary ==================== Name: System.spur-cmm.728 Author: eem Time: 7 May 2015, 5:08:15.525 pm UUID: c2d22606-9b84-4d52-9650-649d5df24121 Ancestors: System-cmm.728 System-cmm.728 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Restored the much safer version of Preferences class>>#preferenceAt:ifAbsent:. =============== Diff against System-cmm.728 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:46:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:46:46 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.729.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.729.mcz ==================== Summary ==================== Name: System.spur-kfr.729 Author: eem Time: 7 May 2015, 5:08:29.288 pm UUID: 874a7d4b-d4db-4fab-a0ab-789c8546a4f9 Ancestors: System-kfr.729, System.spur-cmm.728 System-kfr.729 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Add a 'refresh this menu' item to the Standard System Fonts menu, so it can update to reflect the current selected fonts =============== Diff against System-kfr.729 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:47:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:47:10 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.730.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.730.mcz ==================== Summary ==================== Name: System.spur-kfr.730 Author: eem Time: 7 May 2015, 5:08:47.709 pm UUID: 66e674f8-8169-4264-a16e-e873f04936a2 Ancestors: System-kfr.730, System.spur-kfr.729 System-kfr.730 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Make sure the menu icons are added if needed to Standard System Fonts menu =============== Diff against System-kfr.730 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:47:56 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:48:02 2015 Subject: [squeak-dev] The Trunk: System.spur-nice.731.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-nice.731.mcz ==================== Summary ==================== Name: System.spur-nice.731 Author: eem Time: 7 May 2015, 5:09:06.215 pm UUID: c9a21ee2-a0aa-4201-b9b3-a4402654d7c0 Ancestors: System-nice.731, System.spur-kfr.730 System-nice.731 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 A DummyStream may do nothing, but shall mimic the answer of a regular stream. =============== Diff against System-nice.731 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:49:20 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:49:23 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.733.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.733.mcz ==================== Summary ==================== Name: System.spur-topa.733 Author: eem Time: 7 May 2015, 5:09:30.556 pm UUID: 16321788-68d9-4880-bf4f-3ea1dda9abee Ancestors: System-topa.733, System.spur-nice.732 System-topa.733 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Make a preference to dis/enable the Object History. =============== Diff against System-topa.733 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:50:16 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:50:18 2015 Subject: [squeak-dev] The Trunk: System.spur-topa.734.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-topa.734.mcz ==================== Summary ==================== Name: System.spur-topa.734 Author: eem Time: 7 May 2015, 5:09:40.236 pm UUID: d68cb1cb-85ea-4d3c-8af9-351ac9138b42 Ancestors: System-topa.734, System.spur-topa.733 System-topa.734 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 (typo) =============== Diff against System-topa.734 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:50:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:50:27 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.735.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.735.mcz ==================== Summary ==================== Name: System.spur-kfr.735 Author: eem Time: 7 May 2015, 5:09:49.335 pm UUID: f60d5cfe-f06e-44b2-bcb9-8cd33e82a393 Ancestors: System-kfr.735, System.spur-topa.734 System-kfr.735 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Changes to use SystemNavigation thoroughSenders: true =============== Diff against System-kfr.735 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:51:45 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:51:47 2015 Subject: [squeak-dev] The Trunk: System.spur-kfr.736.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-kfr.736.mcz ==================== Summary ==================== Name: System.spur-kfr.736 Author: eem Time: 7 May 2015, 5:09:57.962 pm UUID: b2852e31-2f0c-4a77-9e65-fb9507d3cc80 Ancestors: System-kfr.736, System.spur-kfr.735 System-kfr.736 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 Changes to use pragma preferences where implemented =============== Diff against System-kfr.736 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Mon May 11 18:52:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 11 18:52:08 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.737.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.737.mcz ==================== Summary ==================== Name: System.spur-ul.737 Author: eem Time: 7 May 2015, 5:10:04.589 pm UUID: 10e7bd8d-c549-426c-a70e-e33c850be706 Ancestors: System-ul.737, System.spur-kfr.736 System-ul.737 patched for Spur by SpurBootstrapMonticelloPackagePatcher * Cog-eem.265 #groupBy:having -> #groupBy: =============== Diff against System-ul.737 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From lecteur at zogotounga.net Mon May 11 19:56:33 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Mon May 11 19:56:32 2015 Subject: [squeak-dev] Can't upload to SqueakMap Message-ID: <55510971.3070002@zogotounga.net> Hello, These last days, I could not upload anything to SqueakMap: the connection resets after a few seconds. Could someone take a look at this ? Thanks. Stef From dnorton at mindspring.com Tue May 12 01:13:18 2015 From: dnorton at mindspring.com (Dan Norton) Date: Tue May 12 01:13:21 2015 Subject: [squeak-dev] Activity Message-ID: <555153AE.22072.248C868@dnorton.mindspring.com> Good to see that Squeak-dev is still active ;-) From asqueaker at gmail.com Tue May 12 01:46:04 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 12 01:46:06 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: <55510971.3070002@zogotounga.net> References: <55510971.3070002@zogotounga.net> Message-ID: Do you mean from a webbrowser or the in-image UI? On Mon, May 11, 2015 at 2:56 PM, St?phane Rollandin wrote: > Hello, > > These last days, I could not upload anything to SqueakMap: the connection > resets after a few seconds. Could someone take a look at this ? > > Thanks. > > Stef > From commits at source.squeak.org Tue May 12 01:48:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 01:48:45 2015 Subject: [squeak-dev] The Trunk: MonticelloConfigurations-dtl.131.mcz Message-ID: David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk: http://source.squeak.org/trunk/MonticelloConfigurations-dtl.131.mcz ==================== Summary ==================== Name: MonticelloConfigurations-dtl.131 Author: dtl Time: 4 May 2015, 4:12:33.318 pm UUID: 2e9a311b-a484-4f84-af4e-96dd6d373bfe Ancestors: MonticelloConfigurations-mt.130 Let MCMcmUpdater be instance based. The default system updater is MCMcmUpdater default. Updaters are associated with repositories ('http://source.squeak.org/trunk'), and are kept in a registry (MCMcmUpdater updaters) keyed by repository URL. Each updater has its own updateMapName (such as 'update' or 'update.spur') and maintains its own lastUpdateMap. System preferences apply to the default updater. A SqueakMap package head stream can specify its update map name independent of the Squeak trunk update stream preference, for example: "MCMcmUpdater updateMapName: 'update.oscog' repository: 'http://source.squeak.org/VMMaker' =============== Diff against MonticelloConfigurations-mt.130 =============== Item was changed: Object subclass: #MCMcmUpdater + instanceVariableNames: 'updateMapName lastUpdateMap' + classVariableNames: 'DefaultUpdateURL LastUpdateMap SkipPackages UpdateFromServerAtStartup UpdateMapName UpdateMissingPackages Updaters' - instanceVariableNames: '' - classVariableNames: 'DefaultUpdateURL LastUpdateMap SkipPackages UpdateFromServerAtStartup UpdateMapName UpdateMissingPackages' poolDictionaries: '' category: 'MonticelloConfigurations'! + !MCMcmUpdater commentStamp: 'dtl 5/4/2015 16:03' prior: 0! - !MCMcmUpdater commentStamp: 'cbc 8/26/2010 16:42' prior: 0! MCMcmUpdater provides utility methods for updating Monticello packages from Monticello configurations. When Monticello configurations are stored in a repository (or repositories), MCMcmUpdater acts as an update stream. It first ensures that each configuration map has been loaded in sequence, then updates the last configuration map to the most recent version for each specified package, and finally loads these versions to produce a fully updated configuration. Currently if a set of packages are unloaded from the image, using this class to reload them may cause problems, depending on what dependencies those classes have. Success is not assured. Removing packages via SmalltalkImage>>unloadAllKnownPackages will be successful, it flags the packages removed so that they are not loaded by this utility. If you wish to not have MCMcmUpdater update packages, there are two ways to handle this: 1) To have MCMcmUpdater not update any packages not currently in the image set the UpdateMissingPackages preference to false: MCMcmUpdater updateMissingPackages: false Note that any new packages added to the repositories will not be picked up when this is turned off. 2) To have MCMcmUpdater not update a specific package, evaluate MCMcmUpdater disableUpdatesOfPackage: Class Variables definitions: DefaultUpdateURL - String: the URL that will be checked by default for updates. This would be set for a common standard location to check. + Updaters - A dictionary of MCMcmUpdater instances keyed by repository URL. - LastUpdateMap - Dictionary of Integer: version number of the last loaded update map per repository. Keeps track of the last configuration map, so that the utility will not have to run through the full history in the repositories each time you ask to update. SkipPackages - Set of Strings: names of packages to not update in MCMcmUpdater (empty by default). UpdateMissingPackages - Boolean: if true (default), new packages in the update config map will be loaded unless they are in SkipPackages. If false, packages not currently loaded in the image will not be loaded by MCMcmUpdater. (This can be dangerous if packages are split - use at your own risk). + + Instance Variables: + + updateMapName - Base name of the files used for this updater, typically a name such as 'update' or 'update.spur'. + + lastUpdateMap - Dictionary of Integer: version number of the last loaded update map per repository. Keeps track of the last configuration map, so that the utility will not have to run through the full history in the repositories each time you ask to update. ! Item was added: + ----- Method: MCMcmUpdater class>>default (in category 'instance creation') ----- + default + "The default instance for system updates. Uses a default update map + name that may be set as a preference to enable a specific update stream + for a repository." + + ^ self updaters + at: self defaultUpdateURL + ifAbsentPut: [self updateMapName: self updateMapName]! Item was changed: ----- Method: MCMcmUpdater class>>initialize (in category 'class initialization') ----- initialize "MCMcmUpdater initialize" LastUpdateMap ifNil:[ LastUpdateMap := Dictionary new. ]. DefaultUpdateURL ifNil:[ DefaultUpdateURL := MCHttpRepository trunkUrlString. + ]. + Updaters := nil. + self flag: #FIXME. + "The next line is to faciliate updating from class-side methods to instance based. + Building a new default update map is very time consuming, so do not do it. + Delete this after the transition is complete. Also delete class var LastUpdateMap + and its initialization above. -dtl May 2015" + LastUpdateMap ifNotNil: [ self default lastUpdateMap: LastUpdateMap ] + ! - ].! Item was removed: - ----- Method: MCMcmUpdater class>>refreshUpdateMapFor:with: (in category 'updating') ----- - refreshUpdateMapFor: r with: updateList - "Update the LastUpdateMap and answer a possibly reduced updateList" - - | config | - (LastUpdateMap at: r description ifAbsent: [0]) = 0 ifTrue: [ - "No update has ever been loaded from this repo. If no package is - present in the image either, we can skip right to the latest config" - config := r versionNamed: updateList last value. - (config dependencies anySatisfy: [:dep| dep package hasWorkingCopy]) - ifFalse: [ (self useLatestPackagesFrom: r) - ifTrue: [LastUpdateMap at: r description put: updateList last key. - ^ #()] - ifFalse: [ ^ updateList last: 1]]]. - ^ updateList - ! Item was changed: + ----- Method: MCMcmUpdater class>>skipPackages (in category 'preferences') ----- - ----- Method: MCMcmUpdater class>>skipPackages (in category 'private') ----- skipPackages ^SkipPackages ifNil: [SkipPackages := Set new]! Item was removed: - ----- Method: MCMcmUpdater class>>updateFromConfig: (in category 'updating') ----- - updateFromConfig: config - - "Skip packages that were specifically unloaded" - config dependencies: (config dependencies - reject: [:dep| self skipPackages includes: dep package name]). - self updateMissingPackages ifFalse:[ - "Skip packages that are not in the image" - config dependencies: (config dependencies - select: [:dep| dep package hasWorkingCopy])]. - (config dependencies allSatisfy:[:dep| dep isFulfilled]) - ifFalse:[config upgrade]. - ! Item was removed: - ----- Method: MCMcmUpdater class>>updateFromDefaultRepository (in category 'updating') ----- - updateFromDefaultRepository - "Update from the default repository only" - ^self updateFromRepositories: {self defaultUpdateURL}! Item was changed: ----- Method: MCMcmUpdater class>>updateFromRepositories: (in category 'updating') ----- updateFromRepositories: repositoryUrls "MCMcmUpdater updateFromRepositories: #( 'http://squeaksource.com/MCUpdateTest' )" + ^ self default updateFromRepositories: repositoryUrls! - | repos config | - MCConfiguration upgradeIsMerge: true. - LastUpdateMap ifNil:[LastUpdateMap := Dictionary new]. - "The list of repositories to consult in order" - repos := repositoryUrls collect:[:url| - MCRepositoryGroup default repositories - detect:[:r| r description = url] - ifNone:[ | r | - r := MCHttpRepository location: url user: '' password: ''. - MCRepositoryGroup default addRepository: r. - r]]. - - "The list of updates-author.version.mcm sorted by version" - repos do:[ :r | config := self updateFromRepository: r ]. - ^config! Item was added: + ----- Method: MCMcmUpdater class>>updateFromRepositories:using:baseName: (in category 'updating') ----- + updateFromRepositories: repositoryUrls using: updaterUrlKey baseName: baseName + "Update all repositoryUrls using an MCMcmUpdater identified by updaterUrlKey, and + using update map baseName" + + ^ (self updateMapName: baseName repository: updaterUrlKey) + updateFromRepositories: repositoryUrls! Item was removed: - ----- Method: MCMcmUpdater class>>updateFromRepository: (in category 'updating') ----- - updateFromRepository: repository - - | config | - repository cacheAllFileNamesDuring: [ | updateList | - updateList := self updateListFor: repository. - "Proceed only if there are updates available at all." - updateList ifNotEmpty: [ - updateList := self refreshUpdateMapFor: repository with: updateList. - "Now process each update file. Check if we have all dependencies and if not, - load the entire configuration (this is mostly to skip older updates quickly)" - updateList do:[:assoc| - ProgressNotification signal: '' extra: 'Processing ', assoc value. - config := repository versionNamed: assoc value. - self updateFromConfig: config. - LastUpdateMap at: repository description put: assoc key. - ] displayingProgress: 'Processing configurations'. - "We've loaded all the provided update configurations. - Use the latest configuration to update all the remaining packages." - (self useLatestPackagesFrom: repository) ifTrue: [ - config updateFromRepositories. - config upgrade]. - ]]. - ^ config - ! Item was changed: ----- Method: MCMcmUpdater class>>updateFromServer (in category 'updating') ----- updateFromServer "Update the image by loading all pending updates from the server." + + ^self default updateFromServer + ! - | config | - "Flush all caches. If a previous download failed this is often helpful" - MCFileBasedRepository flushAllCaches. - config := MCMcmUpdater updateFromDefaultRepository. - config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. - config setSystemVersion. - self inform: ('Update completed. - Current update number: ' translated, SystemVersion current highestUpdate).! Item was removed: - ----- Method: MCMcmUpdater class>>updateListFor: (in category 'private') ----- - updateListFor: repo - - | updateList allNames minVersion | - updateList := OrderedCollection new. - minVersion := LastUpdateMap at: repo description ifAbsent: [0]. - "Find all the update-*.mcm files" - allNames := 'Checking ', repo description - displayProgressFrom: 0 to: 1 during: [:bar| - bar value: 0. - repo allFileNamesOrCache ]. - allNames do: [:fileName | | version | - ((fileName endsWith: '.mcm') - and: [fileName packageAndBranchName = self updateMapName - and: [(version := fileName versionNumber) >= minVersion]]) - ifTrue: [updateList add: version -> fileName]]. - ^updateList sort! Item was changed: + ----- Method: MCMcmUpdater class>>updateMapName: (in category 'instance creation') ----- + updateMapName: baseName + "Answer a new instance with a base update name baseName such as + 'update' or 'update.oscog' " + + ^ self new updateMapName: baseName! - ----- Method: MCMcmUpdater class>>updateMapName: (in category 'preferences') ----- - updateMapName: aString - "Name for update map, without version info" - UpdateMapName := aString! Item was added: + ----- Method: MCMcmUpdater class>>updateMapName:repository: (in category 'instance creation') ----- + updateMapName: baseName repository: url + "Answer an instance for the given repository URL with a base update name + baseName. The instance will be updated in the Updaters dictionary if baseName + has changed." + + | updater | + updater := self updaters at: url ifAbsentPut: [ self updateMapName: baseName ]. + updater updateMapName = baseName + ifFalse: [ ^ self updaters at: url put: (self updateMapName: baseName )]. + ^ updater + ! Item was added: + ----- Method: MCMcmUpdater class>>updateUsing:baseName: (in category 'updating') ----- + updateUsing: updaterUrlKey baseName: baseName + "Update using an MCMcmUpdater identified by updaterUrlKey, and using + update map baseName" + + ^ (self updateMapName: baseName repository: updaterUrlKey) updateFromServer + ! Item was added: + ----- Method: MCMcmUpdater class>>updaters (in category 'accessing') ----- + updaters + "A dictionary of updaters, including the system default, indexed by repository URL" + + ^ Updaters ifNil: [ Updaters := Dictionary new ]! Item was removed: - ----- Method: MCMcmUpdater class>>useLatestPackagesFrom: (in category 'private') ----- - useLatestPackagesFrom: repo - "for overriding on a per repository basis" - ^true! Item was added: + ----- Method: MCMcmUpdater>>lastUpdateMap (in category 'accessing') ----- + lastUpdateMap + + ^ lastUpdateMap ifNil: [ lastUpdateMap := Dictionary new ] + ! Item was added: + ----- Method: MCMcmUpdater>>lastUpdateMap: (in category 'accessing') ----- + lastUpdateMap: aDictionary + + lastUpdateMap := aDictionary + ! Item was added: + ----- Method: MCMcmUpdater>>refreshUpdateMapFor:with: (in category 'updating') ----- + refreshUpdateMapFor: r with: updateList + "Update the lastUpdateMap and answer a possibly reduced updateList" + + | config | + (lastUpdateMap at: r description ifAbsent: [0]) = 0 ifTrue: [ + "No update has ever been loaded from this repo. If no package is + present in the image either, we can skip right to the latest config" + config := r versionNamed: updateList last value. + (config dependencies anySatisfy: [:dep| dep package hasWorkingCopy]) + ifFalse: [ (self useLatestPackagesFrom: r) + ifTrue: [lastUpdateMap at: r description put: updateList last key. + ^ #()] + ifFalse: [ ^ updateList last: 1]]]. + ^ updateList + ! Item was added: + ----- Method: MCMcmUpdater>>skipPackages (in category 'private') ----- + skipPackages + ^SkipPackages ifNil: [SkipPackages := Set new]! Item was added: + ----- Method: MCMcmUpdater>>updateFromConfig: (in category 'updating') ----- + updateFromConfig: config + + "Skip packages that were specifically unloaded" + config dependencies: (config dependencies + reject: [:dep| self class skipPackages includes: dep package name]). + self class updateMissingPackages ifFalse:[ + "Skip packages that are not in the image" + config dependencies: (config dependencies + select: [:dep| dep package hasWorkingCopy])]. + (config dependencies allSatisfy:[:dep| dep isFulfilled]) + ifFalse:[config upgrade]. + ! Item was added: + ----- Method: MCMcmUpdater>>updateFromDefaultRepository (in category 'updating') ----- + updateFromDefaultRepository + "Update from the default repository only" + ^self updateFromRepositories: {self class defaultUpdateURL}! Item was added: + ----- Method: MCMcmUpdater>>updateFromRepositories: (in category 'updating') ----- + updateFromRepositories: repositoryUrls + "MCMcmUpdater updateFromRepositories: #( + 'http://squeaksource.com/MCUpdateTest' + )" + + | repos config | + MCConfiguration upgradeIsMerge: true. + "The list of repositories to consult in order" + repos := repositoryUrls collect:[:url| + MCRepositoryGroup default repositories + detect:[:r| r description = url] + ifNone:[ | r | + r := MCHttpRepository location: url user: '' password: ''. + MCRepositoryGroup default addRepository: r. + r]]. + + "The list of updates-author.version.mcm sorted by version" + repos do:[ :r | config := self updateFromRepository: r ]. + ^config! Item was added: + ----- Method: MCMcmUpdater>>updateFromRepository: (in category 'updating') ----- + updateFromRepository: repository + + | config | + repository cacheAllFileNamesDuring: [ | updateList | + updateList := self updateListFor: repository. + "Proceed only if there are updates available at all." + updateList ifNotEmpty: [ + updateList := self refreshUpdateMapFor: repository with: updateList. + "Now process each update file. Check if we have all dependencies and if not, + load the entire configuration (this is mostly to skip older updates quickly)" + updateList do:[:assoc| + ProgressNotification signal: '' extra: 'Processing ', assoc value. + config := repository versionNamed: assoc value. + self updateFromConfig: config. + self lastUpdateMap at: repository description put: assoc key. + ] displayingProgress: 'Processing configurations'. + "We've loaded all the provided update configurations. + Use the latest configuration to update all the remaining packages." + (self useLatestPackagesFrom: repository) ifTrue: [ + config updateFromRepositories. + config upgrade]. + ]]. + ^ config + ! Item was added: + ----- Method: MCMcmUpdater>>updateFromServer (in category 'updating') ----- + updateFromServer + "Update the image by loading all pending updates from the server." + | config | + "Flush all caches. If a previous download failed this is often helpful" + MCFileBasedRepository flushAllCaches. + config := MCMcmUpdater default updateFromDefaultRepository. + config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. + config setSystemVersion. + self inform: ('Update completed. + Current update number: ' translated, SystemVersion current highestUpdate).! Item was added: + ----- Method: MCMcmUpdater>>updateListFor: (in category 'private') ----- + updateListFor: repo + + | updateList allNames minVersion | + updateList := OrderedCollection new. + minVersion := self lastUpdateMap at: repo description ifAbsent: [0]. + "Find all the update-*.mcm files" + allNames := 'Checking ', repo description + displayProgressFrom: 0 to: 1 during: [:bar| + bar value: 0. + repo allFileNamesOrCache ]. + allNames do: [:fileName | | version | + ((fileName endsWith: '.mcm') + and: [fileName packageAndBranchName = self updateMapName + and: [(version := fileName versionNumber) >= minVersion]]) + ifTrue: [updateList add: version -> fileName]]. + ^updateList sort! Item was added: + ----- Method: MCMcmUpdater>>updateMapName (in category 'accessing') ----- + updateMapName + "Name for update map, without version info" + + ^ updateMapName ifNil: [updateMapName := self class updateMapName]! Item was added: + ----- Method: MCMcmUpdater>>updateMapName: (in category 'accessing') ----- + updateMapName: aString + "Name for update map, without version info" + updateMapName := aString! Item was added: + ----- Method: MCMcmUpdater>>useLatestPackagesFrom: (in category 'private') ----- + useLatestPackagesFrom: repo + "for overriding on a per repository basis" + ^true! From commits at source.squeak.org Tue May 12 01:49:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 01:49:04 2015 Subject: [squeak-dev] The Trunk: MonticelloConfigurations-dtl.132.mcz Message-ID: David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk: http://source.squeak.org/trunk/MonticelloConfigurations-dtl.132.mcz ==================== Summary ==================== Name: MonticelloConfigurations-dtl.132 Author: dtl Time: 10 May 2015, 12:46:15.656 pm UUID: 5cee23dd-fe38-41b9-afe0-25fb80f6ede7 Ancestors: MonticelloConfigurations-dtl.131 Fix updating from streams other than the default. For example: MCMcmUpdater updateFromRepository: 'http://www.squeaksource.com/OSProcess' baseName: 'update' =============== Diff against MonticelloConfigurations-dtl.131 =============== Item was added: + ----- Method: MCMcmUpdater class>>defaultBaseName (in category 'updating') ----- + defaultBaseName + "If not otherwise specified, look for update maps with this base name" + + ^ 'update'! Item was added: + ----- Method: MCMcmUpdater class>>updateFromRepository: (in category 'updating') ----- + updateFromRepository: updaterUrlKey + "Update using an MCMcmUpdater identified by updaterUrlKey using the default + update map baseName" + + ^ self updateFromRepository: updaterUrlKey baseName: self defaultBaseName + ! Item was added: + ----- Method: MCMcmUpdater class>>updateFromRepository:baseName: (in category 'updating') ----- + updateFromRepository: updaterUrlKey baseName: baseName + "Update using an MCMcmUpdater identified by updaterUrlKey, and using + update map baseName" + + ^ (self updateMapName: baseName repository: updaterUrlKey) + updateFrom: updaterUrlKey! Item was changed: ----- Method: MCMcmUpdater class>>updateFromServer (in category 'updating') ----- updateFromServer "Update the image by loading all pending updates from the server." + ^self default updateFrom: self defaultUpdateURL - ^self default updateFromServer ! Item was removed: - ----- Method: MCMcmUpdater class>>updateUsing:baseName: (in category 'updating') ----- - updateUsing: updaterUrlKey baseName: baseName - "Update using an MCMcmUpdater identified by updaterUrlKey, and using - update map baseName" - - ^ (self updateMapName: baseName repository: updaterUrlKey) updateFromServer - ! Item was added: + ----- Method: MCMcmUpdater>>updateFrom: (in category 'updating') ----- + updateFrom: url + "Update the image by loading all pending updates from the server." + | config | + "Flush all caches. If a previous download failed this is often helpful" + MCFileBasedRepository flushAllCaches. + config := self updateFromRepositories: { url }. + config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. + config setSystemVersion. + self inform: ('Update completed. + Current update number: ' translated, SystemVersion current highestUpdate).! Item was removed: - ----- Method: MCMcmUpdater>>updateFromServer (in category 'updating') ----- - updateFromServer - "Update the image by loading all pending updates from the server." - | config | - "Flush all caches. If a previous download failed this is often helpful" - MCFileBasedRepository flushAllCaches. - config := MCMcmUpdater default updateFromDefaultRepository. - config ifNil: [^self inform: 'Unable to retrieve updates from remote repository.' translated]. - config setSystemVersion. - self inform: ('Update completed. - Current update number: ' translated, SystemVersion current highestUpdate).! From commits at source.squeak.org Tue May 12 01:49:17 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 01:49:18 2015 Subject: [squeak-dev] The Trunk: MonticelloConfigurations-dtl.133.mcz Message-ID: David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk: http://source.squeak.org/trunk/MonticelloConfigurations-dtl.133.mcz ==================== Summary ==================== Name: MonticelloConfigurations-dtl.133 Author: dtl Time: 10 May 2015, 7:38:29.29 pm UUID: d5d2f00e-20d2-4e1e-bb26-6f087e3d9c28 Ancestors: MonticelloConfigurations-dtl.132 MCMcmUpdater>>refreshUpdateMapFor:with: should not answer an empty update list in the case of a package that has not yet been loaded. Fixes an existing bug, not related to the refactoring in the last two updates. =============== Diff against MonticelloConfigurations-dtl.132 =============== Item was changed: ----- Method: MCMcmUpdater>>refreshUpdateMapFor:with: (in category 'updating') ----- refreshUpdateMapFor: r with: updateList "Update the lastUpdateMap and answer a possibly reduced updateList" | config | (lastUpdateMap at: r description ifAbsent: [0]) = 0 ifTrue: [ "No update has ever been loaded from this repo. If no package is present in the image either, we can skip right to the latest config" config := r versionNamed: updateList last value. + (config dependencies anySatisfy: [:dep | dep package hasWorkingCopy]) + ifFalse: [(self useLatestPackagesFrom: r) + ifTrue: [lastUpdateMap at: r description put: updateList last key]. + updateList isEmpty + ifTrue: [^ #()] + ifFalse: [^ updateList last: 1]]]. - (config dependencies anySatisfy: [:dep| dep package hasWorkingCopy]) - ifFalse: [ (self useLatestPackagesFrom: r) - ifTrue: [lastUpdateMap at: r description put: updateList last key. - ^ #()] - ifFalse: [ ^ updateList last: 1]]]. ^ updateList ! From Das.Linux at gmx.de Tue May 12 05:22:50 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue May 12 05:22:53 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <7916095.5.1431396965131.JavaMail.jenkins@box3-squeak> References: <15876228.4.1431373534969.JavaMail.jenkins@box3-squeak> <7916095.5.1431396965131.JavaMail.jenkins@box3-squeak> Message-ID: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> Dear all we have as strange MNU on the CI, (MessageNotUnderstood: ByteSymbol>>width:color:) can someone look into this? Best regards -Tobias On 12.05.2015, at 04:16, squeak-ci wrote: > See > > ------------------------------------------ > [...truncated 53 lines...] > (Command started with PID 25813) > "/tmp/d20150512-25795-110yz31/bld/ckformat" " > After format conversion: " image format 6504 > === BUILD FINISHED > cp -r /tmp/d20150512-25795-12q4abx > cp -r /tmp/d20150512-25795-zlj6l4 > Using existing cog r.3332 > Using existing interpreter VM in > Using /tmp/d20150512-25795-zlj6l4/bld/squeak.sh > Preparing to update image of Squeak4.6 vintage > > spawning command 1 with timeout 1500 seconds: "/tmp/d20150512-25795-12q4abx/cog.r3332/coglinux/bin/squeak" "-vm-sound-null" "-vm-display-null" " "../update-image.st" > 2015-05-12T03:50:56.784+01:00: Updating http://source.squeak.org/trunk > 2015-05-12T03:50:57.988+01:00: Checking http://source.squeak.org/trunk > vvvvvvvvvvvvvvvvvv MessageNotUnderstood: ByteSymbol>>width:color: vvvvvvvvvvvvvvvvvv > The time is 2015-05-12T03:54:13.594+01:00 > ByteSymbol(Object)>>doesNotUnderstand: #width:color: > PluggableSystemWindow(BorderedMorph)>>borderStyle > MethodContext(Morph)>>drawOn: > MethodContext(Canvas)>>draw: > MethodContext(Canvas)>>drawMorph: > MethodContext(Morph)>>fullDrawOn: > MethodContext(Canvas)>>fullDraw: > MethodContext(Canvas)>>fullDrawMorph: > [] in [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(Rectangle)>>allAreasOutsideList:startingAt:do: > MethodContext(Rectangle)>>allAreasOutsideList:do: > [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(SequenceableCollection)>>do: > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(WorldState)>>displayWorld:submorphs: > MethodContext(PasteUpMorph)>>privateOuterDisplayWorld > MethodContext(PasteUpMorph)>>displayWorld > [] in MethodContext(SystemProgressMorph)>>position:label:min:max: > [] in [] in MethodContext(Collection)>>do:displayingProgress:every: > MethodContext(OrderedCollection)>>do: > [] in MethodContext(Collection)>>do:displayingProgress:every: > [] in [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(BlockClosure)>>on:do: > [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(BlockClosure)>>ensure: > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(ProgressInitiationException)>>defaultResumeValue > MethodContext(Exception)>>resume > MethodContext(ProgressInitiationException)>>defaultAction > MethodContext(UndefinedObject)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(Exception)>>signal > MethodContext(ProgressInitiationException)>>display:at:from:to:during: > MethodContext(ProgressInitiationException class)>>display:at:from:to:during: > MethodContext(String)>>displayProgressAt:from:to:during: > MethodContext(String)>>displayProgressFrom:to:during: > MethodContext(Collection)>>do:displayingProgress:every: > MethodContext(Collection)>>do:displayingProgress: > [] in [] in [] in [] in MethodContext(MCPackageLoader)>>basicLoad > MethodContext(BlockClosure)>>on:do: > [] in [] in [] in MethodContext(MCPackageLoader)>>basicLoad > MethodContext(BlockClosure)>>on:do: > MethodContext(CurrentReadOnlySourceFiles class)>>cacheDuring: > [] in [] in MethodContext(MCPackageLoader)>>basicLoad > MethodContext(BlockClosure)>>ensure: > [] in MethodContext(MCPackageLoader)>>basicLoad > MethodContext(BlockClosure)>>ensure: > MethodContext(RecentMessages)>>suspendWhile: > MethodContext(MCPackageLoader)>>basicLoad > [] in MethodContext(MCPackageLoader)>>loadWithNameLike: > MethodContext(BlockClosure)>>ensure: > MethodContext(MCPackageLoader)>>useChangeSetNamed:during: > MethodContext(MCPackageLoader)>>useNewChangeSetNamedLike:during: > MethodContext(MCPackageLoader)>>loadWithNameLike: > MethodContext(MCVersionLoader)>>load > MethodContext(MCVersionLoader class)>>loadVersion: > MethodContext(MCVersion)>>load > [] in MethodContext(MCConfiguration)>>upgrade > [] in [] in MethodContext(MCConfiguration)>>depsSatisfying:versionDo:displayingProgress: > MethodContext(OrderedCollection)>>do: > MethodContext(MCConfiguration)>>withProgress:in:do: > [] in MethodContext(MCConfiguration)>>depsSatisfying:versionDo:displayingProgress: > MethodContext(MCFileBasedRepository)>>cacheAllFileNamesDuring: > [] in [] in MethodContext(MCConfiguration)>>cacheAllFileNamesDuring: > MethodContext(MCConfiguration)>>cacheAllFileNamesDuring: > MethodContext(MCConfiguration)>>depsSatisfying:versionDo:displayingProgress: > MethodContext(MCConfiguration)>>upgrade > [] in [] in [] in [] in MethodContext(MCMcmUpdater class)>>updateFromRepositories: > [] in [] in MethodContext(Collection)>>do:displayingProgress:every: > MethodContext(OrderedCollection)>>do: > [] in MethodContext(Collection)>>do:displayingProgress:every: > [] in [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(BlockClosure)>>on:do: > [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(BlockClosure)>>ensure: > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(ProgressInitiationException)>>defaultResumeValue > MethodContext(Exception)>>resume > [] in [] in MethodContext(UndefinedObject)>>DoIt > MethodContext(BlockClosure)>>cull: > [] in MethodContext(ContextPart)>>handleSignal: > MethodContext(BlockClosure)>>ensure: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(Exception)>>signal > MethodContext(ProgressInitiationException)>>display:at:from:to:during: > MethodContext(ProgressInitiationException class)>>display:at:from:to:during: > MethodContext(String)>>displayProgressAt:from:to:during: > MethodContext(String)>>displayProgressFrom:to:during: > MethodContext(Collection)>>do:displayingProgress:every: > > ^^^^^^^^^^^^^^^^^^ MessageNotUnderstood: ByteSymbol>>width:color: ^^^^^^^^^^^^^^^^^^ > vvvvvvvvvvvvvvvvvv Error: MessageNotUnderstood: ByteSymbol>>width:color: vvvvvvvvvvvvvvvvvv > The time is 2015-05-12T03:54:13.606+01:00 > MethodContext(Object)>>error: > [] in MethodContext(WorldState)>>displayWorldSafely: > MethodContext(BlockClosure)>>cull:cull: > [] in MethodContext(BlockClosure)>>ifError: > MethodContext(BlockClosure)>>cull: > [] in MethodContext(ContextPart)>>handleSignal: > MethodContext(BlockClosure)>>ensure: > MethodContext(ContextPart)>>handleSignal: > MethodContext(Exception)>>signal > MethodContext(Object)>>doesNotUnderstand: #width:color: > MethodContext(BorderedMorph)>>borderStyle > MethodContext(Morph)>>drawOn: > MethodContext(Canvas)>>draw: > MethodContext(Canvas)>>drawMorph: > MethodContext(Morph)>>fullDrawOn: > MethodContext(Canvas)>>fullDraw: > MethodContext(Canvas)>>fullDrawMorph: > [] in [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(Rectangle)>>allAreasOutsideList:startingAt:do: > MethodContext(Rectangle)>>allAreasOutsideList:do: > [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(SequenceableCollection)>>do: > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(WorldState)>>displayWorld:submorphs: > MethodContext(PasteUpMorph)>>privateOuterDisplayWorld > MethodContext(PasteUpMorph)>>displayWorld > [] in MethodContext(WorldState)>>displayWorldSafely: > MethodContext(BlockClosure)>>on:do: > MethodContext(BlockClosure)>>ifError: > MethodContext(WorldState)>>displayWorldSafely: > MethodContext(PasteUpMorph)>>displayWorldSafely > MethodContext(Morph)>>refreshWorld > MethodContext(PluggableTextMorph)>>update: > MethodContext(PluggableTextMorphPlus)>>update: > [] in MethodContext(Object)>>changed: > MethodContext(DependentsArray)>>do: > MethodContext(Object)>>changed: > [] in MethodContext(TranscriptStream)>>endEntry > [] in MethodContext(Semaphore)>>critical: > MethodContext(BlockClosure)>>ensure: > MethodContext(Semaphore)>>critical: > MethodContext(TranscriptStream)>>endEntry > MethodContext(TranscriptStream)>>show: > MethodContext(SmalltalkImage)>>snapshot:andQuit:withExitCode:embedded: > MethodContext(SmalltalkImage)>>snapshot:andQuitWithExitCode: > [] in MethodContext(UndefinedObject)>>DoIt > MethodContext(BlockClosure)>>cull: > [] in MethodContext(ContextPart)>>handleSignal: > MethodContext(BlockClosure)>>ensure: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(Exception)>>signal > MethodContext(Object)>>doesNotUnderstand: > MethodContext(BorderedMorph)>>borderStyle > MethodContext(Morph)>>drawOn: > MethodContext(Canvas)>>draw: > MethodContext(Canvas)>>drawMorph: > MethodContext(Morph)>>fullDrawOn: > MethodContext(Canvas)>>fullDraw: > MethodContext(Canvas)>>fullDrawMorph: > [] in [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(Rectangle)>>allAreasOutsideList:startingAt:do: > MethodContext(Rectangle)>>allAreasOutsideList:do: > [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(SequenceableCollection)>>do: > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > MethodContext(WorldState)>>displayWorld:submorphs: > MethodContext(PasteUpMorph)>>privateOuterDisplayWorld > MethodContext(PasteUpMorph)>>displayWorld > [] in MethodContext(SystemProgressMorph)>>position:label:min:max: > [] in [] in MethodContext(Collection)>>do:displayingProgress:every: > MethodContext(OrderedCollection)>>do: > [] in MethodContext(Collection)>>do:displayingProgress:every: > [] in [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(BlockClosure)>>on:do: > [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(BlockClosure)>>ensure: > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > MethodContext(ProgressInitiationException)>>defaultResumeValue > MethodContext(Exception)>>resume > MethodContext(ProgressInitiationException)>>defaultAction > MethodContext(UndefinedObject)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(ContextPart)>>handleSignal: > MethodContext(Exception)>>signal > > ^^^^^^^^^^^^^^^^^^ Error: MessageNotUnderstood: ByteSymbol>>width:color: ^^^^^^^^^^^^^^^^^^ > (Command started with PID 25842) > !!! Killing command 1 for exceeding allotted time: "/tmp/d20150512-25795-12q4abx/cog.r3332/coglinux/bin/squeak" "-vm-sound-null" "-vm-display-null" " "../update-image.st". > kill -USR1 25842 > rake aborted! > Process 25842 failed with exit status > :393:in `block in run_image_with_cmd' > :26:in `counted_command' > :352:in `run_image_with_cmd' > :84:in `block (2 levels) in ' > :83:in `chdir' > :83:in `block in ' > /var/lib/jenkins/.rvm/gems/ruby-1.9.3-p392/bin/ruby_executable_hooks:15:in `eval' > /var/lib/jenkins/.rvm/gems/ruby-1.9.3-p392/bin/ruby_executable_hooks:15:in `
' > Tasks: TOP => update_base_image > (See full trace by running task with --trace) > > ------------- > Tried to kill process 25842 but it's gone > Process leaked file descriptors. See http://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build for more information > Build step 'Execute shell' marked build as failure > Archiving artifacts > Recording test results > ERROR: Publisher 'Publish JUnit test result report' failed: Test reports were found but none of them are new. Did tests run? > For example, is 23 hr old > > Discard old builds... > #1368 is removed because old than numToKeep From lecteur at zogotounga.net Tue May 12 07:07:50 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Tue May 12 07:07:53 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: References: <55510971.3070002@zogotounga.net> Message-ID: <5551A6C6.8060500@zogotounga.net> > Do you mean from a webbrowser or the in-image UI? From the web. I actually didn't know the UI could be used for uploading :) Stef From Marcel.Taeumel at hpi.de Tue May 12 07:35:08 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 07:51:36 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> Message-ID: <1431416108411-4825928.post@n4.nabble.com> Seems to be a VM bug. CogVM 3306 is fine. 3332 crashes. Windows. Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825928.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 12 07:40:26 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 07:56:56 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <1431416108411-4825928.post@n4.nabble.com> References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431416108411-4825928.post@n4.nabble.com> Message-ID: <1431416426080-4825929.post@n4.nabble.com> 3306 OK 3312 OK 3319 CRASH 3332 CRASH Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825929.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Tue May 12 08:01:56 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 12 08:01:58 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> References: <15876228.4.1431373534969.JavaMail.jenkins@box3-squeak> <7916095.5.1431396965131.JavaMail.jenkins@box3-squeak> <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> Message-ID: I get some wonky answers. It seems to crash because of http://source.squeak.org/inbox/Morphic-DS.916.mcz ??? Reverting this method and the image don't crash. Morph>>innerBounds "Return the inner rectangle enclosed by the bounds of this morph excluding the space taken by its borders. For an unbordered morph, this is just its bounds." ^ self bounds insetBy: self borderStyle inset On Tue, May 12, 2015 at 7:22 AM, Tobias Pape wrote: > Dear all > > we have as strange MNU on the CI, (MessageNotUnderstood: > ByteSymbol>>width:color:) > can someone look into this? > > Best regards > -Tobias > > On 12.05.2015, at 04:16, squeak-ci wrote: > > > See > > > > ------------------------------------------ > > [...truncated 53 lines...] > > (Command started with PID 25813) > > "/tmp/d20150512-25795-110yz31/bld/ckformat" "< > http://build.squeak.org/job/SqueakTrunk/ws/target/TrunkImage.image"> > > After format conversion: "< > http://build.squeak.org/job/SqueakTrunk/ws/target/TrunkImage.image"> > image format 6504 > > === BUILD FINISHED > > cp -r > /tmp/d20150512-25795-12q4abx > > cp -r < > http://build.squeak.org/job/SqueakTrunk/ws/target/Squeak-4.10.2.2614-src-32/.> > /tmp/d20150512-25795-zlj6l4 > > Using existing cog r.3332 > > Using existing interpreter VM in < > http://build.squeak.org/job/SqueakTrunk/ws/target/Squeak-4.10.2.2614-src-32 > > > > Using /tmp/d20150512-25795-zlj6l4/bld/squeak.sh > > Preparing to update image of Squeak4.6 vintage > > > > spawning command 1 with timeout 1500 seconds: > "/tmp/d20150512-25795-12q4abx/cog.r3332/coglinux/bin/squeak" > "-vm-sound-null" "-vm-display-null" "< > http://build.squeak.org/job/SqueakTrunk/ws/target/TrunkImage.image"> "../ > update-image.st" > > 2015-05-12T03:50:56.784+01:00: Updating http://source.squeak.org/trunk > > 2015-05-12T03:50:57.988+01:00: Checking http://source.squeak.org/trunk > > vvvvvvvvvvvvvvvvvv MessageNotUnderstood: ByteSymbol>>width:color: > vvvvvvvvvvvvvvvvvv > > The time is 2015-05-12T03:54:13.594+01:00 > > ByteSymbol(Object)>>doesNotUnderstand: #width:color: > > PluggableSystemWindow(BorderedMorph)>>borderStyle > > MethodContext(Morph)>>drawOn: > > MethodContext(Canvas)>>draw: > > MethodContext(Canvas)>>drawMorph: > > MethodContext(Morph)>>fullDrawOn: > > MethodContext(Canvas)>>fullDraw: > > MethodContext(Canvas)>>fullDrawMorph: > > [] in [] in > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(Rectangle)>>allAreasOutsideList:startingAt:do: > > MethodContext(Rectangle)>>allAreasOutsideList:do: > > [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(SequenceableCollection)>>do: > > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(WorldState)>>displayWorld:submorphs: > > MethodContext(PasteUpMorph)>>privateOuterDisplayWorld > > MethodContext(PasteUpMorph)>>displayWorld > > [] in MethodContext(SystemProgressMorph)>>position:label:min:max: > > [] in [] in MethodContext(Collection)>>do:displayingProgress:every: > > MethodContext(OrderedCollection)>>do: > > [] in MethodContext(Collection)>>do:displayingProgress:every: > > [] in [] in > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(BlockClosure)>>on:do: > > [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(ProgressInitiationException)>>defaultResumeValue > > MethodContext(Exception)>>resume > > MethodContext(ProgressInitiationException)>>defaultAction > > MethodContext(UndefinedObject)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(Exception)>>signal > > MethodContext(ProgressInitiationException)>>display:at:from:to:during: > > MethodContext(ProgressInitiationException > class)>>display:at:from:to:during: > > MethodContext(String)>>displayProgressAt:from:to:during: > > MethodContext(String)>>displayProgressFrom:to:during: > > MethodContext(Collection)>>do:displayingProgress:every: > > MethodContext(Collection)>>do:displayingProgress: > > [] in [] in [] in [] in MethodContext(MCPackageLoader)>>basicLoad > > MethodContext(BlockClosure)>>on:do: > > [] in [] in [] in MethodContext(MCPackageLoader)>>basicLoad > > MethodContext(BlockClosure)>>on:do: > > MethodContext(CurrentReadOnlySourceFiles class)>>cacheDuring: > > [] in [] in MethodContext(MCPackageLoader)>>basicLoad > > MethodContext(BlockClosure)>>ensure: > > [] in MethodContext(MCPackageLoader)>>basicLoad > > MethodContext(BlockClosure)>>ensure: > > MethodContext(RecentMessages)>>suspendWhile: > > MethodContext(MCPackageLoader)>>basicLoad > > [] in MethodContext(MCPackageLoader)>>loadWithNameLike: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(MCPackageLoader)>>useChangeSetNamed:during: > > MethodContext(MCPackageLoader)>>useNewChangeSetNamedLike:during: > > MethodContext(MCPackageLoader)>>loadWithNameLike: > > MethodContext(MCVersionLoader)>>load > > MethodContext(MCVersionLoader class)>>loadVersion: > > MethodContext(MCVersion)>>load > > [] in MethodContext(MCConfiguration)>>upgrade > > [] in [] in > MethodContext(MCConfiguration)>>depsSatisfying:versionDo:displayingProgress: > > MethodContext(OrderedCollection)>>do: > > MethodContext(MCConfiguration)>>withProgress:in:do: > > [] in > MethodContext(MCConfiguration)>>depsSatisfying:versionDo:displayingProgress: > > MethodContext(MCFileBasedRepository)>>cacheAllFileNamesDuring: > > [] in [] in MethodContext(MCConfiguration)>>cacheAllFileNamesDuring: > > MethodContext(MCConfiguration)>>cacheAllFileNamesDuring: > > > MethodContext(MCConfiguration)>>depsSatisfying:versionDo:displayingProgress: > > MethodContext(MCConfiguration)>>upgrade > > [] in [] in [] in [] in MethodContext(MCMcmUpdater > class)>>updateFromRepositories: > > [] in [] in MethodContext(Collection)>>do:displayingProgress:every: > > MethodContext(OrderedCollection)>>do: > > [] in MethodContext(Collection)>>do:displayingProgress:every: > > [] in [] in > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(BlockClosure)>>on:do: > > [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(ProgressInitiationException)>>defaultResumeValue > > MethodContext(Exception)>>resume > > [] in [] in MethodContext(UndefinedObject)>>DoIt > > MethodContext(BlockClosure)>>cull: > > [] in MethodContext(ContextPart)>>handleSignal: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(Exception)>>signal > > MethodContext(ProgressInitiationException)>>display:at:from:to:during: > > MethodContext(ProgressInitiationException > class)>>display:at:from:to:during: > > MethodContext(String)>>displayProgressAt:from:to:during: > > MethodContext(String)>>displayProgressFrom:to:during: > > MethodContext(Collection)>>do:displayingProgress:every: > > > > ^^^^^^^^^^^^^^^^^^ MessageNotUnderstood: ByteSymbol>>width:color: > ^^^^^^^^^^^^^^^^^^ > > vvvvvvvvvvvvvvvvvv Error: MessageNotUnderstood: ByteSymbol>>width:color: > vvvvvvvvvvvvvvvvvv > > The time is 2015-05-12T03:54:13.606+01:00 > > MethodContext(Object)>>error: > > [] in MethodContext(WorldState)>>displayWorldSafely: > > MethodContext(BlockClosure)>>cull:cull: > > [] in MethodContext(BlockClosure)>>ifError: > > MethodContext(BlockClosure)>>cull: > > [] in MethodContext(ContextPart)>>handleSignal: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(Exception)>>signal > > MethodContext(Object)>>doesNotUnderstand: #width:color: > > MethodContext(BorderedMorph)>>borderStyle > > MethodContext(Morph)>>drawOn: > > MethodContext(Canvas)>>draw: > > MethodContext(Canvas)>>drawMorph: > > MethodContext(Morph)>>fullDrawOn: > > MethodContext(Canvas)>>fullDraw: > > MethodContext(Canvas)>>fullDrawMorph: > > [] in [] in > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(Rectangle)>>allAreasOutsideList:startingAt:do: > > MethodContext(Rectangle)>>allAreasOutsideList:do: > > [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(SequenceableCollection)>>do: > > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(WorldState)>>displayWorld:submorphs: > > MethodContext(PasteUpMorph)>>privateOuterDisplayWorld > > MethodContext(PasteUpMorph)>>displayWorld > > [] in MethodContext(WorldState)>>displayWorldSafely: > > MethodContext(BlockClosure)>>on:do: > > MethodContext(BlockClosure)>>ifError: > > MethodContext(WorldState)>>displayWorldSafely: > > MethodContext(PasteUpMorph)>>displayWorldSafely > > MethodContext(Morph)>>refreshWorld > > MethodContext(PluggableTextMorph)>>update: > > MethodContext(PluggableTextMorphPlus)>>update: > > [] in MethodContext(Object)>>changed: > > MethodContext(DependentsArray)>>do: > > MethodContext(Object)>>changed: > > [] in MethodContext(TranscriptStream)>>endEntry > > [] in MethodContext(Semaphore)>>critical: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(Semaphore)>>critical: > > MethodContext(TranscriptStream)>>endEntry > > MethodContext(TranscriptStream)>>show: > > MethodContext(SmalltalkImage)>>snapshot:andQuit:withExitCode:embedded: > > MethodContext(SmalltalkImage)>>snapshot:andQuitWithExitCode: > > [] in MethodContext(UndefinedObject)>>DoIt > > MethodContext(BlockClosure)>>cull: > > [] in MethodContext(ContextPart)>>handleSignal: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(Exception)>>signal > > MethodContext(Object)>>doesNotUnderstand: > > MethodContext(BorderedMorph)>>borderStyle > > MethodContext(Morph)>>drawOn: > > MethodContext(Canvas)>>draw: > > MethodContext(Canvas)>>drawMorph: > > MethodContext(Morph)>>fullDrawOn: > > MethodContext(Canvas)>>fullDraw: > > MethodContext(Canvas)>>fullDrawMorph: > > [] in [] in > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(Rectangle)>>allAreasOutsideList:startingAt:do: > > MethodContext(Rectangle)>>allAreasOutsideList:do: > > [] in MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(SequenceableCollection)>>do: > > MethodContext(WorldState)>>drawWorld:submorphs:invalidAreasOn: > > MethodContext(WorldState)>>displayWorld:submorphs: > > MethodContext(PasteUpMorph)>>privateOuterDisplayWorld > > MethodContext(PasteUpMorph)>>displayWorld > > [] in MethodContext(SystemProgressMorph)>>position:label:min:max: > > [] in [] in MethodContext(Collection)>>do:displayingProgress:every: > > MethodContext(OrderedCollection)>>do: > > [] in MethodContext(Collection)>>do:displayingProgress:every: > > [] in [] in > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(BlockClosure)>>on:do: > > [] in MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(BlockClosure)>>ensure: > > MethodContext(MorphicUIManager)>>displayProgress:at:from:to:during: > > MethodContext(ProgressInitiationException)>>defaultResumeValue > > MethodContext(Exception)>>resume > > MethodContext(ProgressInitiationException)>>defaultAction > > MethodContext(UndefinedObject)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(ContextPart)>>handleSignal: > > MethodContext(Exception)>>signal > > > > ^^^^^^^^^^^^^^^^^^ Error: MessageNotUnderstood: ByteSymbol>>width:color: > ^^^^^^^^^^^^^^^^^^ > > (Command started with PID 25842) > > !!! Killing command 1 for exceeding allotted time: > "/tmp/d20150512-25795-12q4abx/cog.r3332/coglinux/bin/squeak" > "-vm-sound-null" "-vm-display-null" "< > http://build.squeak.org/job/SqueakTrunk/ws/target/TrunkImage.image"> "../ > update-image.st". > > kill -USR1 25842 > > rake aborted! > > Process 25842 failed with exit status > > :393:in > `block in run_image_with_cmd' > > :26:in > `counted_command' > > :352:in > `run_image_with_cmd' > > :84:in `block (2 > levels) in ' > > :83:in `chdir' > > :83:in `block in > ' > > > /var/lib/jenkins/.rvm/gems/ruby-1.9.3-p392/bin/ruby_executable_hooks:15:in > `eval' > > > /var/lib/jenkins/.rvm/gems/ruby-1.9.3-p392/bin/ruby_executable_hooks:15:in > `
' > > Tasks: TOP => update_base_image > > (See full trace by running task with --trace) > > > > ------------- > > Tried to kill process 25842 but it's gone > > Process leaked file descriptors. See > http://wiki.jenkins-ci.org/display/JENKINS/Spawning+processes+from+build > for more information > > Build step 'Execute shell' marked build as failure > > Archiving artifacts > > Recording test results > > ERROR: Publisher 'Publish JUnit test result report' failed: Test reports > were found but none of them are new. Did tests run? > > For example, < > http://build.squeak.org/job/SqueakTrunk/ws/target/BalloonTests-Test.xml> > is 23 hr old > > > > Discard old builds... > > #1368 is removed because old than numToKeep > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/b81a272d/attachment.htm From Marcel.Taeumel at hpi.de Tue May 12 08:10:27 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 08:26:57 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> Message-ID: <1431418227756-4825931.post@n4.nabble.com> I think that's only a symptom. Why else is the bug related to different VM versions? The only thing that might change if you revert that code is the time to crash because border computation is deferred to a later point in time. :) Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825931.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 12 08:11:24 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 08:27:51 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <1431418227756-4825931.post@n4.nabble.com> References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> Message-ID: <1431418284625-4825932.post@n4.nabble.com> Oh, wait. There are two implementations of #borderStyle. Let me double-check. Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825932.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 12 08:14:38 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 08:31:05 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <1431418284625-4825932.post@n4.nabble.com> References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> Message-ID: <1431418478752-4825933.post@n4.nabble.com> No, even Morph >> #borderStyle assumes that there is an instance of BorderStyle returned. So Morphic-DS.916.mcz is fine. If you take a look at the strack trace and the implementation of BorderedMorph >> #borderStyle, you can see that #width:color: is only sent to the class BorderStyle, which strangely happens to be a ByteSymbol in recent VMs. So it's a VM bug. Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825933.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 12 08:22:58 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 08:39:25 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: References: <1431180976415-4825440.post@n4.nabble.com> Message-ID: <1431418978931-4825935.post@n4.nabble.com> Hey, I do account for all of those. It might only be a slip because the documentation is poor. :P As for Message Names, it should be built with ToolBuilder to also work in MVC. So that rules out (!) all Morph-specific features. What lies in the Tools package, must not assume Morph API. Yes, there might be a need for MorphicTools as a specialization for tools that want to benefit from Morphic-only features. :P As for now, you can trigger the search with CMD+S. That's only one (half) keystroke more. ;) As for the future, yes, we can just implement a flag in PluggableInputFieldSpec to support multi-line input fields if desired. However, I consider the "eye jump" that occurs with multi-line fields on overflow quite distracting for input fields. :-) --- We have code-freeze. So if I should add that now, make a vote. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4825935.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Tue May 12 08:47:12 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 12 08:47:16 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <1431418478752-4825933.post@n4.nabble.com> References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> <1431418478752-4825933.post@n4.nabble.com> Message-ID: There is also BorderStyle class inset and BorderStyle inset. One returns a class, one a integer. BorderStyle simple inset => nil ? Karl On Tue, May 12, 2015 at 10:14 AM, marcel.taeumel wrote: > No, even Morph >> #borderStyle assumes that there is an instance of > BorderStyle returned. So Morphic-DS.916.mcz is fine. > > If you take a look at the strack trace and the implementation of > BorderedMorph >> #borderStyle, you can see that #width:color: is only sent > to the class BorderStyle, which strangely happens to be a ByteSymbol in > recent VMs. > > So it's a VM bug. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825933.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/42ebb387/attachment.htm From Marcel.Taeumel at hpi.de Tue May 12 08:31:14 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 08:47:42 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk Message-ID: <1431419474638-4825937.post@n4.nabble.com> Hi, there! Do we want to support and maintain regular expressions in trunk? http://www.squeaksource.com/Regex.html Best, Marcel -- View this message in context: http://forum.world.st/Support-Regular-Expressions-in-Trunk-tp4825937.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Tue May 12 08:56:26 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 12 08:56:30 2015 Subject: [squeak-dev] The Inbox: Morphic-DS.916.mcz In-Reply-To: <55376b26.8854e50a.7ef1.ffffe60bSMTPIN_ADDED_MISSING@mx.google.com> References: <55376b26.8854e50a.7ef1.ffffe60bSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Maybe we need SimpleBorder>>width ^width ifNil:[ ^0] Karl On Wed, Apr 22, 2015 at 11:34 AM, wrote: > A new version of Morphic was added to project The Inbox: > http://source.squeak.org/inbox/Morphic-DS.916.mcz > > ==================== Summary ==================== > > Name: Morphic-DS.916 > Author: DS > Time: 22 April 2015, 11:33:53.08 am > UUID: e58e8bbb-7a37-954a-87a0-5e71904b55c2 > Ancestors: Morphic-cmm.915 > > Add basic support for borderStyles with non-uniform widths. > > =============== Diff against Morphic-cmm.915 =============== > > Item was added: > + ----- Method: BorderStyle>>inset (in category 'accessing') ----- > + inset > + "Possible inset when honoring this border style. The default > implementation uses #width to return a uniform inset." > + ^ self width! > > Item was changed: > ----- Method: Canvas>>fillRectangle:fillStyle:borderStyle: (in category > 'drawing-rectangles') ----- > fillRectangle: aRectangle fillStyle: aFillStyle borderStyle: aBorderStyle > "Fill the given rectangle." > aFillStyle isTransparent ifFalse:[ > + self fillRectangle: (aRectangle insetBy: aBorderStyle > inset) fillStyle: aFillStyle]. > - self fillRectangle: (aRectangle insetBy: aBorderStyle > width) fillStyle: aFillStyle]. > aBorderStyle ifNil:[^self]. > aBorderStyle width <= 0 ifTrue:[^self]. > + aBorderStyle frameRectangle: aRectangle on: self.! > - aBorderStyle frameRectangle: aRectangle on: self > - ! > > Item was changed: > ----- Method: Morph>>innerBounds (in category 'geometry') ----- > innerBounds > "Return the inner rectangle enclosed by the bounds of this morph > excluding the space taken by its borders. For an unbordered morph, this is > just its bounds." > > + ^ self bounds insetBy: self borderStyle inset! > - ^ self bounds insetBy: self borderWidth! > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/ff279c4f/attachment.htm From karlramberg at gmail.com Tue May 12 08:57:42 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 12 08:57:44 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> <1431418478752-4825933.post@n4.nabble.com> Message-ID: Maybe we need SimpleBorder>>width ^width ifNil:[ ^0] On Tue, May 12, 2015 at 10:47 AM, karl ramberg wrote: > There is also BorderStyle class inset and BorderStyle inset. > One returns a class, one a integer. > > BorderStyle simple inset => nil ? > > Karl > > On Tue, May 12, 2015 at 10:14 AM, marcel.taeumel > wrote: > >> No, even Morph >> #borderStyle assumes that there is an instance of >> BorderStyle returned. So Morphic-DS.916.mcz is fine. >> >> If you take a look at the strack trace and the implementation of >> BorderedMorph >> #borderStyle, you can see that #width:color: is only sent >> to the class BorderStyle, which strangely happens to be a ByteSymbol in >> recent VMs. >> >> So it's a VM bug. >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: >> http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825933.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/88eac5f5/attachment.htm From karlramberg at gmail.com Tue May 12 10:02:54 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 12 10:02:56 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> <1431418478752-4825933.post@n4.nabble.com> Message-ID: SimpleBorder>>width ^width ifNil:[0] I'll push this to trunk if there are no protests. Simple stuff like this should work: RectangleMorph new borderStyle: BorderStyle simple; openInWorld Karl On Tue, May 12, 2015 at 10:57 AM, karl ramberg wrote: > Maybe we need > SimpleBorder>>width > ^width ifNil:[ ^0] > > On Tue, May 12, 2015 at 10:47 AM, karl ramberg > wrote: > >> There is also BorderStyle class inset and BorderStyle inset. >> One returns a class, one a integer. >> >> BorderStyle simple inset => nil ? >> >> Karl >> >> On Tue, May 12, 2015 at 10:14 AM, marcel.taeumel >> wrote: >> >>> No, even Morph >> #borderStyle assumes that there is an instance of >>> BorderStyle returned. So Morphic-DS.916.mcz is fine. >>> >>> If you take a look at the strack trace and the implementation of >>> BorderedMorph >> #borderStyle, you can see that #width:color: is only >>> sent >>> to the class BorderStyle, which strangely happens to be a ByteSymbol in >>> recent VMs. >>> >>> So it's a VM bug. >>> >>> Best, >>> Marcel >>> >>> >>> >>> -- >>> View this message in context: >>> http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825933.html >>> Sent from the Squeak - Dev mailing list archive at Nabble.com. >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/5657e5d3/attachment.htm From karlramberg at gmail.com Tue May 12 10:13:43 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 12 10:13:47 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> <1431418478752-4825933.post@n4.nabble.com> Message-ID: BorderStyle>>inset that return the width is not a good method, since there is a BorderStyle named #inset. This will just obfuscate. Here one should use BorderStyle>>width instead Karl On Tue, May 12, 2015 at 12:02 PM, karl ramberg wrote: > SimpleBorder>>width > ^width ifNil:[0] > > I'll push this to trunk if there are no protests. > > Simple stuff like this should work: > RectangleMorph new borderStyle: BorderStyle simple; openInWorld > > Karl > > On Tue, May 12, 2015 at 10:57 AM, karl ramberg > wrote: > >> Maybe we need >> SimpleBorder>>width >> ^width ifNil:[ ^0] >> >> On Tue, May 12, 2015 at 10:47 AM, karl ramberg >> wrote: >> >>> There is also BorderStyle class inset and BorderStyle inset. >>> One returns a class, one a integer. >>> >>> BorderStyle simple inset => nil ? >>> >>> Karl >>> >>> On Tue, May 12, 2015 at 10:14 AM, marcel.taeumel >>> wrote: >>> >>>> No, even Morph >> #borderStyle assumes that there is an instance of >>>> BorderStyle returned. So Morphic-DS.916.mcz is fine. >>>> >>>> If you take a look at the strack trace and the implementation of >>>> BorderedMorph >> #borderStyle, you can see that #width:color: is only >>>> sent >>>> to the class BorderStyle, which strangely happens to be a ByteSymbol in >>>> recent VMs. >>>> >>>> So it's a VM bug. >>>> >>>> Best, >>>> Marcel >>>> >>>> >>>> >>>> -- >>>> View this message in context: >>>> http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825933.html >>>> Sent from the Squeak - Dev mailing list archive at Nabble.com. >>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/b143d291/attachment.htm From bert at freudenbergs.de Tue May 12 10:23:12 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue May 12 10:23:15 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> Message-ID: <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> (moving to squeak-dev) On 12.05.2015, at 03:54, Chris Muller wrote: > > The update stream wasn't smooth for me because there were numerous > merge prompts where I wasn't sure whether I should "Keep Local" or > "Keep Remote". I selected Local every time, is that right? No you want to ?keep remote?, meaning you want the changes coming in from the new package to supersede the changes in your local image. We wanted to give these buttons better labels for a long time. How about ?keep my changes? vs ?discard my changes?? And ?keep all my changes? vs ?discard all my changes? instead of ?rest local/remote?? Some native speaker help us out, here ;) - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/b45f7b8f/smime.bin From karlramberg at gmail.com Tue May 12 10:41:42 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 12 10:41:45 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> Message-ID: What about: 'Skip' 'leave method in image untouched' 'Load' 'load method from file' and 'Skip all' 'leave all methods in image untouched' 'Load all' 'load all methods from file' On Tue, May 12, 2015 at 12:23 PM, Bert Freudenberg wrote: > (moving to squeak-dev) > > On 12.05.2015, at 03:54, Chris Muller wrote: > > > > The update stream wasn't smooth for me because there were numerous > > merge prompts where I wasn't sure whether I should "Keep Local" or > > "Keep Remote". I selected Local every time, is that right? > > No you want to ?keep remote?, meaning you want the changes coming in from > the new package to supersede the changes in your local image. > > We wanted to give these buttons better labels for a long time. > > How about ?keep my changes? vs ?discard my changes?? And ?keep all my > changes? vs ?discard all my changes? instead of ?rest local/remote?? > > Some native speaker help us out, here ;) > > - Bert - > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/2cf18d65/attachment.htm From commits at source.squeak.org Tue May 12 11:20:13 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 11:20:15 2015 Subject: [squeak-dev] The Trunk: Morphic-kfr.980.mcz Message-ID: Karl Ramberg uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-kfr.980.mcz ==================== Summary ==================== Name: Morphic-kfr.980 Author: kfr Time: 12 May 2015, 1:19:10.645 pm UUID: c692ab81-8c12-484f-bf45-3ab75e0ebb1f Ancestors: Morphic-cmm.979 BorderStyle width should not return nil =============== Diff against Morphic-cmm.979 =============== Item was changed: ----- Method: SimpleBorder>>width (in category 'accessing') ----- width + ^width ifNil:[0]! - ^width! From lewis at mail.msen.com Tue May 12 11:58:21 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 12 11:58:24 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <1431419474638-4825937.post@n4.nabble.com> References: <1431419474638-4825937.post@n4.nabble.com> Message-ID: <20150512115821.GA27214@shell.msen.com> On Tue, May 12, 2015 at 01:31:14AM -0700, marcel.taeumel wrote: > Hi, there! > > Do we want to support and maintain regular expressions in trunk? > > http://www.squeaksource.com/Regex.html > The latest version loads and runs fine in Squeak, and the tests pass. Why does it need to be in trunk? Dave From lewis at mail.msen.com Tue May 12 12:05:44 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 12 12:05:45 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> References: <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> Message-ID: <20150512120544.GB27214@shell.msen.com> On Tue, May 12, 2015 at 12:23:12PM +0200, Bert Freudenberg wrote: > (moving to squeak-dev) > > On 12.05.2015, at 03:54, Chris Muller wrote: > > > > The update stream wasn't smooth for me because there were numerous > > merge prompts where I wasn't sure whether I should "Keep Local" or > > "Keep Remote". I selected Local every time, is that right? > > No you want to ???keep remote???, meaning you want the changes coming in from the new package to supersede the changes in your local image. > > We wanted to give these buttons better labels for a long time. > > How about ???keep my changes??? vs ???discard my changes???? And ???keep all my changes??? vs ???discard all my changes??? instead of ???rest local/remote???? > > Some native speaker help us out, here ;) > +1 "keep my changes" and "discard my changes" sounds good to me, and is easier for me to understand. Dave From bert at freudenbergs.de Tue May 12 12:15:05 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue May 12 12:15:08 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch Message-ID: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> Newsworthy? https://www.kickstarter.com/projects/1598272670/chip-the-worlds-first-9-computer - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/f3ec4097/smime.bin From Marcel.Taeumel at hpi.de Tue May 12 13:28:29 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 13:45:00 2015 Subject: [squeak-dev] Re: Support Regular Expressions in Trunk In-Reply-To: <20150512115821.GA27214@shell.msen.com> References: <1431419474638-4825937.post@n4.nabble.com> <20150512115821.GA27214@shell.msen.com> Message-ID: <1431437309985-4825995.post@n4.nabble.com> Not sure. Just thinking about normal programming activities. Squeak's Strings can only do simple things. There may be some wildcard matching hidden, not sure. It just feels like that regular expressions should be supported out-of-the-box. Best, Marcel -- View this message in context: http://forum.world.st/Support-Regular-Expressions-in-Trunk-tp4825937p4825995.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 12 13:31:15 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 13:47:44 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> <1431418478752-4825933.post@n4.nabble.com> Message-ID: <1431437475098-4825996.post@n4.nabble.com> It's a fall-back. Inset may be a scalar, a point, or a rectangle. See Rectangle interface for more information. Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825996.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 12 13:33:53 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 13:50:22 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <1431437475098-4825996.post@n4.nabble.com> References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> <1431418478752-4825933.post@n4.nabble.com> <1431437475098-4825996.post@n4.nabble.com> Message-ID: <1431437633692-4825999.post@n4.nabble.com> Anyway, new border styles should not return nil on #width. The former implementation of Morph >> #innerBounds did use #borderWidth and BorderedMorph actually does overwrite this. This is not good because BorderStyle instances are used all over the place. Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4825999.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 12 13:44:54 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 14:01:23 2015 Subject: [squeak-dev] Re: Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <1431437633692-4825999.post@n4.nabble.com> References: <1431418227756-4825931.post@n4.nabble.com> <1431418284625-4825932.post@n4.nabble.com> <1431418478752-4825933.post@n4.nabble.com> <1431437475098-4825996.post@n4.nabble.com> <1431437633692-4825999.post@n4.nabble.com> Message-ID: <1431438294779-4826000.post@n4.nabble.com> Maybe for clarification: BorderStyle >> #inset is for non-uniform border styles. I did not manage to implement one as an example yet, but all the hooks are placed for this: http://imgsrv.worldstart.com/ct-images/draw-border-old-excel.gif Morphic drawing code makes double-dispatch into BorderStyle >> #frameRectangle:on:. There, you can draw non-uniform borders. :-) But right, having #inset on both class-side and instance-side is confusing..... :-/ Best, Marcel -- View this message in context: http://forum.world.st/Re-Build-failed-in-Jenkins-SqueakTrunk-1472-tp4825918p4826000.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From tim.olson.mail at gmail.com Tue May 12 14:59:50 2015 From: tim.olson.mail at gmail.com (Tim Olson) Date: Tue May 12 15:00:23 2015 Subject: [squeak-dev] Build failed in Jenkins: SqueakTrunk #1472 In-Reply-To: <1431418227756-4825931.post@n4.nabble.com> References: <7B187F8C-488B-44D2-A5F1-C1B4E6804FF7@gmx.de> <1431418227756-4825931.post@n4.nabble.com> Message-ID: <1A53F319-1DCD-4473-BD25-9B103601D36D@gmail.com> On May 12, 2015, at 3:10 AM, marcel.taeumel wrote: > I think that's only a symptom. Why else is the bug related to different VM > versions? I ran into this and various variants of it a little while ago, when I tried to update my somewhat outdated image using the latest Cog VM. When I ran using an older interpreter VM, the build went fine. In tracking down one of the MNU failures I was seeing with the Cog build, I saw this: SmallInteger(Object) >> doesNotUnderstand: #isEmptyOrNil PluggableListMorphOfMany(PluggableListMorph) >> hasFilter where: hasFilter ^ lastKeystrokes isEmptyOrNil not the debugger in the context of hasFilter says that lastKeystrokes is an empty ByteString, but when I click on self for the SmallInteger DNU, it says that the receiver is a SmallInteger 0. Looking at the object context of PluggableListMorphOfMany, I saw that the only SmallInteger 0 value was the instance variable ?lastKeystrokeTime? just before ?lastKeystrokes?. So it looks to me like there may be a (rare) instance variable to register mapping bug in the latest Cog VMs. ? tim From leves at elte.hu Tue May 12 15:07:46 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 12 15:07:52 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <1431419474638-4825937.post@n4.nabble.com> References: <1431419474638-4825937.post@n4.nabble.com> Message-ID: Definitely. I've been playing with the idea - while I was working on my still unreleased DNS package - but I came to the conclusion that the VM side has to be cleaned first. The plugin should use the platform's support library, instead of some ~10 years old version. I was also playing with the idea of using the RE2 engine instead of PCRE, but it's probably a lot more work to make it happen. Levente On Tue, 12 May 2015, marcel.taeumel wrote: > Hi, there! > > Do we want to support and maintain regular expressions in trunk? > > http://www.squeaksource.com/Regex.html > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/Support-Regular-Expressions-in-Trunk-tp4825937.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From leves at elte.hu Tue May 12 15:20:05 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 12 15:20:10 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: <20150512120544.GB27214@shell.msen.com> References: <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> <20150512120544.GB27214@shell.msen.com> Message-ID: On Tue, 12 May 2015, David T. Lewis wrote: > On Tue, May 12, 2015 at 12:23:12PM +0200, Bert Freudenberg wrote: >> (moving to squeak-dev) >> >> On 12.05.2015, at 03:54, Chris Muller wrote: >>> >>> The update stream wasn't smooth for me because there were numerous >>> merge prompts where I wasn't sure whether I should "Keep Local" or >>> "Keep Remote". I selected Local every time, is that right? >> >> No you want to ???keep remote???, meaning you want the changes coming in from the new package to supersede the changes in your local image. >> >> We wanted to give these buttons better labels for a long time. >> >> How about ???keep my changes??? vs ???discard my changes???? And ???keep all my changes??? vs ???discard all my changes??? instead of ???rest local/remote???? >> >> Some native speaker help us out, here ;) >> > > +1 > > "keep my changes" and "discard my changes" sounds good to me, and is > easier for me to understand. That sounds misleading to me, because it's possible that those changes are not my changes at all, but different versions of the same method from two branches. Levente > > Dave > > > From leves at elte.hu Tue May 12 15:23:22 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 12 15:23:24 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> Message-ID: On Tue, 12 May 2015, Bert Freudenberg wrote: > (moving to squeak-dev) > > On 12.05.2015, at 03:54, Chris Muller wrote: >> >> The update stream wasn't smooth for me because there were numerous >> merge prompts where I wasn't sure whether I should "Keep Local" or >> "Keep Remote". I selected Local every time, is that right? > > No you want to ?keep remote?, meaning you want the changes coming in from the new package to supersede the changes in your local image. Chris is talking about the update of a Spur image, so - if I'm not mistaken - he has to reject all changes - aka "Keep Local" -, because those changes are from the non-spur branch (no idea how they get there) and try to revert some Spur-related changes (e.g. throwing away the minVal/maxVal class variables from SmallInteger). Levente > > We wanted to give these buttons better labels for a long time. > > How about ?keep my changes? vs ?discard my changes?? And ?keep all my changes? vs ?discard all my changes? instead of ?rest local/remote?? > > Some native speaker help us out, here ;) > > - Bert - > > From commits at source.squeak.org Tue May 12 15:33:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 15:33:28 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.635.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.635.mcz ==================== Summary ==================== Name: Collections.spur-mt.635 Author: eem Time: 12 May 2015, 8:32:57.913 am UUID: c43a4119-fcf3-461d-9017-ed86adb56592 Ancestors: Collections-mt.635, Collections.spur-ul.634 Collections-mt.635 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.266 Some debug code removed from html readwriter.. =============== Diff against Collections-mt.635 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 12 May 2015 3:33:26.276 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From hmm at heeg.de Tue May 12 15:56:19 2015 From: hmm at heeg.de (Hans-Martin Mosner) Date: Tue May 12 15:56:23 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: References: <1431419474638-4825937.post@n4.nabble.com> Message-ID: <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> Am 12.05.2015 17:07, schrieb Levente Uzonyi: > Definitely. I've been playing with the idea - while I was working on > my still unreleased DNS package - but I came to the conclusion that > the VM side has to be cleaned first. > The plugin should use the platform's support library, instead of some > ~10 years old version. Please, no! It's much easier to work with some old library that has consistent behaviour everywhere than it is to find and work around the differences between platform libraries e.g. on Windows, Linux, and some regular UNIX variant. At work I need to do that with VA Smalltalk code page conversion (UTF-8 to ISO8859L1 and back) - code that works on the client doesn't work on the server, so there's a special case and workaround needed to get everything right. The only acceptable option if you really want to use an external library would be to include a standard regex C library with well-defined functionality in the VM. Cheers, Hans-Martin From asqueaker at gmail.com Tue May 12 16:42:19 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 12 16:42:21 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: <1431418978931-4825935.post@n4.nabble.com> References: <1431180976415-4825440.post@n4.nabble.com> <1431418978931-4825935.post@n4.nabble.com> Message-ID: On Tue, May 12, 2015 at 3:22 AM, marcel.taeumel wrote: > Hey, I do account for all of those. It might only be a slip because the > documentation is poor. :P > > As for Message Names, it should be built with ToolBuilder to also work in > MVC. So that rules out (!) all Morph-specific features. What lies in the > Tools package, must not assume Morph API. Well, I really don't understand that logic. There is already very little that can be done in a MVC project today compared to a Morphic project, and I find it hard to believe MVC cannot have a field which does something when Return is pressed anyway. And if its true why not improve MVC than restrict Morphic-based UI's? I also think it is good to really ask what is the benefit of having multiple... errr, "two" UI frameworks which do exactly the same thing? Isn't it their _differences_ which would appeal us to choose one over another? Sometimes I think we get too hung up on the idea of "uniformity" -- not only is it never achieved, I'm begining to feel dubious about it as a goal in the first place. Seriously, I'd be suprised if anyone could articulate a compelling reason in one or two sentences.. > Yes, there might be a need for MorphicTools as a specialization for tools > that want to benefit from Morphic-only features. :P > > As for now, you can trigger the search with CMD+S. That's only one (half) > keystroke more. ;) It's not about the required effort, its about the non-standard behavior for a search field. When you use Google, do you actually click the magnifying glass or press Return? Be honest. What would a new user think if Return didn't work? > As for the future, yes, we can just implement a flag in > PluggableInputFieldSpec to support multi-line input fields if desired. > However, I consider the "eye jump" that occurs with multi-line fields on > overflow quite distracting for input fields. :-) --- We have code-freeze. So > if I should add that now, make a vote. We are in feature freeze, not a code freeze. This seems like a unnecessary usability bug for new users. Say, you never said what function CR's serve in that input field. Do they serve a use-case? From tim at rowledge.org Tue May 12 17:11:21 2015 From: tim at rowledge.org (tim Rowledge) Date: Tue May 12 17:11:27 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> Message-ID: <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> On 12-05-2015, at 5:15 AM, Bert Freudenberg wrote: > Newsworthy? > > https://www.kickstarter.com/projects/1598272670/chip-the-worlds-first-9-computer It *could* be an interesting thing, but there appear to be some problems. For example, it only has a composite video out, so a fairly expensive adaptor is need to use any likely monitor. Not an issue of course for headless usage. Except they are touting the uses as a desktop machine - hey, even Scratch, wonder if they?ve adopted my improved version - which sort of needs a monitor. And the shipping is *$20*. And it only has half as much memory as a Pi, which apparently was a totally killer problem for the Pi until the Pi 2 came out. And open source bigots^H^H^H^H^Hafficionados are complaining about the use of an AllWinner soc. On the other hand it has wi-fi & BT included. As an IoT platform it seems like it would have a good place in the world, if the shipping didn?t make it essentially as expensive as a Pi but without the backup, community and educational raison. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful Latin Phrases:- Utinam coniurati te in foro interficiant! = May conspirators assassinate you in the mall! From tim at rowledge.org Tue May 12 17:27:20 2015 From: tim at rowledge.org (tim Rowledge) Date: Tue May 12 17:27:28 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> Message-ID: <1E7F613D-8AEF-488C-A23B-E1F7C6C26131@rowledge.org> I love the idea of well-integrated expressions etc being available for string handling and in tools. The tricky bit is that ?well-integrated?. If at all possible it should be done without any extra primitives. Unless we have a convincing use case for such string handling needing to be frequently done and very fast I don?t see much value in adding more C code. With Cog and SISTA making the system so much faster we have to consider the possibility that doing all the marshalling, converting, stack fapping, c-code calling, returning, re-converting may take more time than leaving it to Smalltalk. I suppose the counter-argument would be that using a standard library guarantees correct results. Except of course we have a lot of experience with supposedly standard libraries being utterly screwed. Jpeg libraries, anyone? ALSA? As for the actual expression grammar, I imagine most people would be assuming the unix regexp form which has the advantage that a lot of people are familiar with it. And the disadvantage that a very large number of people are not. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful random insult:- Went to the dentist to have his cranial cavity filled. From tim at rowledge.org Tue May 12 17:29:42 2015 From: tim at rowledge.org (tim Rowledge) Date: Tue May 12 17:29:47 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: References: <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> <20150512120544.GB27214@shell.msen.com> Message-ID: <135B5447-0A97-4E70-90D4-94287CBE27D0@rowledge.org> How about ?accept this change? and ?keep current version?. As long as there is a clear indication of the changes it should be ok. Currently I try to remember it as ?red is ready to come in, blue is about to be blown away?. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Oxymorons: Resident alien From lewis at mail.msen.com Tue May 12 17:59:32 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 12 17:59:36 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: References: <1431180976415-4825440.post@n4.nabble.com> <1431418978931-4825935.post@n4.nabble.com> Message-ID: <57023.136.2.1.104.1431453572.squirrel@webmail.msen.com> > On Tue, May 12, 2015 at 3:22 AM, marcel.taeumel > wrote: >> Hey, I do account for all of those. It might only be a slip because the >> documentation is poor. :P >> >> As for Message Names, it should be built with ToolBuilder to also work >> in >> MVC. So that rules out (!) all Morph-specific features. What lies in the >> Tools package, must not assume Morph API. > > Well, I really don't understand that logic. There is already very > little that can be done in a MVC project today compared to a Morphic > project, and I find it hard to believe MVC cannot have a field which > does something when Return is pressed anyway. And if its true why not > improve MVC than restrict Morphic-based UI's? If you are only every going to have one flavor of UI framework, then you do not need a ToolBuilder in the first place. If you *do* want to have a ToolBuilder, then you had better make sure that it works at some suitable level of abstraction. In practice this means applying it to more than one flavor of UI. I would like to think that we might have more flavors of UI technology in the future (Juan's Morphic3, touch devices, Pharo developments, maybe others). But for now we only Morphic and MVC to work with. The good news is that Morphic and MVC are sufficiently different that they provide a very good basis for validating the ToolBuilder abstractions. Dave From bert at freudenbergs.de Tue May 12 18:33:54 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue May 12 18:33:58 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> Message-ID: <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> > On 12.05.2015, at 19:11, tim Rowledge wrote: > > > On 12-05-2015, at 5:15 AM, Bert Freudenberg wrote: > >> Newsworthy? >> >> https://www.kickstarter.com/projects/1598272670/chip-the-worlds-first-9-computer > > It *could* be an interesting thing, but there appear to be some problems. > For example, it only has a composite video out, so a fairly expensive adaptor is need to use any likely monitor. Not an issue of course for headless usage. Except they are touting the uses as a desktop machine - hey, even Scratch, wonder if they?ve adopted my improved version - which sort of needs a monitor. And the shipping is *$20*. And it only has half as much memory as a Pi, which apparently was a totally killer problem for the Pi until the Pi 2 came out. And open source bigots^H^H^H^H^Hafficionados are complaining about the use of an AllWinner soc. > On the other hand it has wi-fi & BT included. > > As an IoT platform it seems like it would have a good place in the world, if the shipping didn?t make it essentially as expensive as a Pi but without the backup, community and educational raison. Whatever its flaws, it?s yet another platform shipping Squeak by default, so I thought that we might capitalize on that while it?s in the news. - Bert - -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/d8cf6d12/smime.bin From asqueaker at gmail.com Tue May 12 18:34:39 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 12 18:34:43 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> Message-ID: +1 And, it would really be nice to have the ability to edit the method right there in case a manual integration is needed, otherwise you have to remember.. On Tue, May 12, 2015 at 5:41 AM, karl ramberg wrote: > What about: > 'Skip' 'leave method in image untouched' > 'Load' 'load method from file' > > and > > 'Skip all' 'leave all methods in image untouched' > 'Load all' 'load all methods from file' > > > > On Tue, May 12, 2015 at 12:23 PM, Bert Freudenberg > wrote: >> >> (moving to squeak-dev) >> >> On 12.05.2015, at 03:54, Chris Muller wrote: >> > >> > The update stream wasn't smooth for me because there were numerous >> > merge prompts where I wasn't sure whether I should "Keep Local" or >> > "Keep Remote". I selected Local every time, is that right? >> >> No you want to ?keep remote?, meaning you want the changes coming in from >> the new package to supersede the changes in your local image. >> >> We wanted to give these buttons better labels for a long time. >> >> How about ?keep my changes? vs ?discard my changes?? And ?keep all my >> changes? vs ?discard all my changes? instead of ?rest local/remote?? >> >> Some native speaker help us out, here ;) >> >> - Bert - >> >> >> >> > > > > From Marcel.Taeumel at hpi.de Tue May 12 18:43:04 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 18:59:35 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: <57023.136.2.1.104.1431453572.squirrel@webmail.msen.com> References: <1431180976415-4825440.post@n4.nabble.com> <1431418978931-4825935.post@n4.nabble.com> <57023.136.2.1.104.1431453572.squirrel@webmail.msen.com> Message-ID: <1431456184473-4826067.post@n4.nabble.com> I also plan to add an abstraction for my Widgets project [1] to support ToolBuilder-based tools. :) Best, Marcel [1] https://github.com/hpi-swa/widgets -- View this message in context: http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4826067.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Tue May 12 19:03:02 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 19:03:04 2015 Subject: [squeak-dev] The Trunk: ToolBuilder-Kernel-mt.89.mcz Message-ID: Marcel Taeumel uploaded a new version of ToolBuilder-Kernel to project The Trunk: http://source.squeak.org/trunk/ToolBuilder-Kernel-mt.89.mcz ==================== Summary ==================== Name: ToolBuilder-Kernel-mt.89 Author: mt Time: 12 May 2015, 9:02:56.628 pm UUID: 5175a13e-cae3-8f48-bd99-8a7d0d012866 Ancestors: ToolBuilder-Kernel-mt.88 Allow input fields to provide soft-line-wrap. =============== Diff against ToolBuilder-Kernel-mt.88 =============== Item was changed: ----- Method: PluggableInputFieldSpec>>softLineWrap (in category 'accessing') ----- softLineWrap + ^ super softLineWrap ifNil: [false]! - ^ false! From commits at source.squeak.org Tue May 12 19:04:55 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 19:04:57 2015 Subject: [squeak-dev] The Trunk: Tools-mt.625.mcz Message-ID: Marcel Taeumel uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-mt.625.mcz ==================== Summary ==================== Name: Tools-mt.625 Author: mt Time: 12 May 2015, 9:04:37.267 pm UUID: 21ada962-eb84-d340-8015-d51b6eb18839 Ancestors: Tools-mt.624 Fixed a regression in Message Names tool to support both line-wrap and CR-to-search. =============== Diff against Tools-mt.624 =============== Item was changed: ----- Method: MessageNames>>buildSearchPaneWith: (in category 'toolbuilder') ----- buildSearchPaneWith: builder | panelSpec textSpec buttonSpec | panelSpec := builder pluggablePanelSpec new layout: #horizontal; children: OrderedCollection new; yourself. + textSpec := builder pluggableInputFieldSpec new. - textSpec := builder pluggableTextSpec new. textSpec model: searchString; help: 'Type here, then hit Search.' translated; getText: #contents; + setText: #contents:; + softLineWrap: true. - setText: #contents:. panelSpec children add: textSpec. buttonSpec := builder pluggableActionButtonSpec new. buttonSpec model: self; label: 'Search'; action: #doSearch; horizontalResizing: #shrinkWrap. panelSpec children add: buttonSpec. ^ panelSpec! From Marcel.Taeumel at hpi.de Tue May 12 18:53:36 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 12 19:10:06 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: References: <1431180976415-4825440.post@n4.nabble.com> <1431418978931-4825935.post@n4.nabble.com> Message-ID: <1431456816385-4826072.post@n4.nabble.com> CRs have no purpose in the message name patterns. Fixed here: http://forum.world.st/The-Trunk-Tools-mt-625-mcz-td4826069.html I find line-wrapping in input fields awkward because of the "gaze jump" there on overflow. In multi-line fields, however, I do account for that... hmmm... Maybe we could span the input field to take the whole width of message names? Would single-line be enough then? Eliot?^^ (After the release, not now...) Still: The button in Message Names is necessary because MVC's PluggableTextView cannot #acceptOnCR and my time is too limited to add all missing features to MVC land right now. :) But I really would like to do that... *sigh* Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4826072.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From ron at usmedrec.com Tue May 12 19:55:27 2015 From: ron at usmedrec.com (Ron Teitelbaum) Date: Tue May 12 19:55:29 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> Message-ID: <03d101d08ced$988ba210$c9a2e630$@usmedrec.com> http://news.squeak.org/2015/05/12/cool-interesting-wait-is-that-scratch/ :) Ron -----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] On Behalf Of Bert Freudenberg Sent: Tuesday, May 12, 2015 2:34 PM To: The general-purpose Squeak developers list Subject: Re: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch > On 12.05.2015, at 19:11, tim Rowledge wrote: > > > On 12-05-2015, at 5:15 AM, Bert Freudenberg wrote: > >> Newsworthy? >> >> https://www.kickstarter.com/projects/1598272670/chip-the-worlds-first-9-comp uter > > It *could* be an interesting thing, but there appear to be some problems. > For example, it only has a composite video out, so a fairly expensive adaptor is need to use any likely monitor. Not an issue of course for headless usage. Except they are touting the uses as a desktop machine - hey, even Scratch, wonder if they've adopted my improved version - which sort of needs a monitor. And the shipping is *$20*. And it only has half as much memory as a Pi, which apparently was a totally killer problem for the Pi until the Pi 2 came out. And open source bigots^H^H^H^H^Hafficionados are complaining about the use of an AllWinner soc. > On the other hand it has wi-fi & BT included. > > As an IoT platform it seems like it would have a good place in the world, if the shipping didn't make it essentially as expensive as a Pi but without the backup, community and educational raison. Whatever its flaws, it's yet another platform shipping Squeak by default, so I thought that we might capitalize on that while it's in the news. - Bert - From bert at freudenbergs.de Tue May 12 20:23:09 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Tue May 12 20:23:16 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <03d101d08ced$988ba210$c9a2e630$@usmedrec.com> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> <03d101d08ced$988ba210$c9a2e630$@usmedrec.com> Message-ID: Thanks, Ron! Not quite sure why you think the Pi did not include Scratch? It did, and does. I think it was the second machine to ship a Squeak application, after Etoys on the OLPC Laptop. Now C.H.I.P. appears to become the third. - Bert - > On 12.05.2015, at 21:55, Ron Teitelbaum wrote: > > http://news.squeak.org/2015/05/12/cool-interesting-wait-is-that-scratch/ > > :) > > Ron > > -----Original Message----- > From: squeak-dev-bounces@lists.squeakfoundation.org > [mailto:squeak-dev-bounces@lists.squeakfoundation.org] On Behalf Of Bert > Freudenberg > Sent: Tuesday, May 12, 2015 2:34 PM > To: The general-purpose Squeak developers list > Subject: Re: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch > > >> On 12.05.2015, at 19:11, tim Rowledge wrote: >> >> >>> On 12-05-2015, at 5:15 AM, Bert Freudenberg wrote: >>> >>> Newsworthy? > https://www.kickstarter.com/projects/1598272670/chip-the-worlds-first-9-comp > uter >> >> It *could* be an interesting thing, but there appear to be some problems. >> For example, it only has a composite video out, so a fairly expensive > adaptor is need to use any likely monitor. Not an issue of course for > headless usage. Except they are touting the uses as a desktop machine - hey, > even Scratch, wonder if they've adopted my improved version - which sort of > needs a monitor. And the shipping is *$20*. And it only has half as much > memory as a Pi, which apparently was a totally killer problem for the Pi > until the Pi 2 came out. And open source bigots^H^H^H^H^Hafficionados are > complaining about the use of an AllWinner soc. >> On the other hand it has wi-fi & BT included. >> >> As an IoT platform it seems like it would have a good place in the world, > if the shipping didn't make it essentially as expensive as a Pi but without > the backup, community and educational raison. > > Whatever its flaws, it's yet another platform shipping Squeak by default, so > I thought that we might capitalize on that while it's in the news. > > - Bert - > > > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 6112 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150512/726bf575/smime.bin From commits at source.squeak.org Tue May 12 21:55:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 12 21:55:07 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150512215505.3730.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008595.html Name: MonticelloConfigurations-dtl.131 Ancestors: MonticelloConfigurations-mt.130 Let MCMcmUpdater be instance based. The default system updater is MCMcmUpdater default. Updaters are associated with repositories ('http://source.squeak.org/trunk'), and are kept in a registry (MCMcmUpdater updaters) keyed by repository URL. Each updater has its own updateMapName (such as 'update' or 'update.spur') and maintains its own lastUpdateMap. System preferences apply to the default updater. A SqueakMap package head stream can specify its update map name independent of the Squeak trunk update stream preference, for example: "MCMcmUpdater updateMapName: 'update.oscog' repository: 'http://source.squeak.org/VMMaker' ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008596.html Name: MonticelloConfigurations-dtl.132 Ancestors: MonticelloConfigurations-dtl.131 Fix updating from streams other than the default. For example: MCMcmUpdater updateFromRepository: 'http://www.squeaksource.com/OSProcess' baseName: 'update' ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008597.html Name: MonticelloConfigurations-dtl.133 Ancestors: MonticelloConfigurations-dtl.132 MCMcmUpdater>>refreshUpdateMapFor:with: should not answer an empty update list in the case of a package that has not yet been loaded. Fixes an existing bug, not related to the refactoring in the last two updates. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008598.html Name: Morphic-kfr.980 Ancestors: Morphic-cmm.979 BorderStyle width should not return nil ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008599.html Name: Collections.spur-mt.635 Ancestors: Collections-mt.635, Collections.spur-ul.634 Collections-mt.635 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.266 Some debug code removed from html readwriter.. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008600.html Name: ToolBuilder-Kernel-mt.89 Ancestors: ToolBuilder-Kernel-mt.88 Allow input fields to provide soft-line-wrap. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008601.html Name: Tools-mt.625 Ancestors: Tools-mt.624 Fixed a regression in Message Names tool to support both line-wrap and CR-to-search. ============================================= From tim at rowledge.org Tue May 12 21:59:21 2015 From: tim at rowledge.org (tim Rowledge) Date: Tue May 12 21:59:29 2015 Subject: [squeak-dev] Keep Local vs Keep Remote when merging In-Reply-To: References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <21648393-63CE-46C7-B663-DB3861E22229@gmx.de> <20150511233538.GA9933@shell.msen.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> Message-ID: <2CF10EB5-6B62-4E25-BFBD-17DE489F4F4B@rowledge.org> On 12-05-2015, at 11:34 AM, Chris Muller wrote: > And, it would really be nice to have the ability to edit the method > right there in case a manual integration is needed, otherwise you have > to remember.. Or if that can?t be done nicely, build a list of such methods and open a suitable methodlist browser at the end of the basic merge. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful random insult:- Talks to plants on their own level. From tim at rowledge.org Tue May 12 22:08:52 2015 From: tim at rowledge.org (tim Rowledge) Date: Tue May 12 22:09:04 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> Message-ID: <8468E841-F556-4414-9763-B2A41C1E322F@rowledge.org> On 12-05-2015, at 11:33 AM, Bert Freudenberg wrote: > > Whatever its flaws, it?s yet another platform shipping Squeak by default, so I thought that we might capitalize on that while it?s in the news. No argument there. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: PIC: Permute Instruction Codes From lewis at mail.msen.com Tue May 12 22:17:09 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 12 22:17:11 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <1E7F613D-8AEF-488C-A23B-E1F7C6C26131@rowledge.org> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> <1E7F613D-8AEF-488C-A23B-E1F7C6C26131@rowledge.org> Message-ID: <20150512221709.GA30292@shell.msen.com> On Tue, May 12, 2015 at 10:27:20AM -0700, tim Rowledge wrote: > I love the idea of well-integrated expressions etc being available for string handling and in tools. The tricky bit is that ?well-integrated?. > > If at all possible it should be done without any extra primitives. Unless we have a convincing use case for such string handling needing to be frequently done and very fast I don?t see much value in adding more C code. With Cog and SISTA making the system so much faster we have to consider the possibility that doing all the marshalling, converting, stack fapping, c-code calling, returning, re-converting may take more time than leaving it to Smalltalk. > I suppose the counter-argument would be that using a standard library guarantees correct results. Except of course we have a lot of experience with supposedly standard libraries being utterly screwed. Jpeg libraries, anyone? ALSA? > > As for the actual expression grammar, I imagine most people would be assuming the unix regexp form which has the advantage that a lot of people are familiar with it. And the disadvantage that a very large number of people are not. > There are two distict packages. The package at www.squeaksource.com/Regex is the Vassili Bykov implementation. It requires no plugin support or special primitives. -- Regular Expression Matcher v 1.1 (C) 1996, 1999 Vassili Bykov -- See `documentation' protocol of RxParser class for user's guide. The PCRE package is Andrew Greenberg's Perl compatible regular expressions. This uses the RePlugin plugin that can be found in the VMMaker package. RePlugin is an internal plugin in the Unix VMs (interpreter/cog/spur), I'm not sure about other platforms or SqueakJS. http://wiki.squeak.org/squeak/558 Dave From Das.Linux at gmx.de Tue May 12 22:35:34 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue May 12 22:35:37 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <20150512221709.GA30292@shell.msen.com> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> <1E7F613D-8AEF-488C-A23B-E1F7C6C26131@rowledge.org> <20150512221709.GA30292@shell.msen.com> Message-ID: On 13.05.2015, at 00:17, David T. Lewis wrote: > On Tue, May 12, 2015 at 10:27:20AM -0700, tim Rowledge wrote: >> I love the idea of well-integrated expressions etc being available for string handling and in tools. The tricky bit is that ?well-integrated?. >> >> If at all possible it should be done without any extra primitives. Unless we have a convincing use case for such string handling needing to be frequently done and very fast I don?t see much value in adding more C code. With Cog and SISTA making the system so much faster we have to consider the possibility that doing all the marshalling, converting, stack fapping, c-code calling, returning, re-converting may take more time than leaving it to Smalltalk. >> I suppose the counter-argument would be that using a standard library guarantees correct results. Except of course we have a lot of experience with supposedly standard libraries being utterly screwed. Jpeg libraries, anyone? ALSA? >> >> As for the actual expression grammar, I imagine most people would be assuming the unix regexp form which has the advantage that a lot of people are familiar with it. And the disadvantage that a very large number of people are not. >> > > There are two distict packages. > > The package at www.squeaksource.com/Regex is the Vassili Bykov implementation. To Quote there: NB. For Pharo users, this package is maintained as part of the core images. For Squeak users, the Pharo repositories might have recent snapshots that weren't actively tested on other branches of Squeak (yet). Just to note that. > It requires no plugin support or special primitives. > > -- Regular Expression Matcher v 1.1 (C) 1996, 1999 Vassili Bykov > -- See `documentation' protocol of RxParser class for user's guide. > > The PCRE package is Andrew Greenberg's Perl compatible regular expressions. > This uses the RePlugin plugin that can be found in the VMMaker package. > RePlugin is an internal plugin in the Unix VMs (interpreter/cog/spur), I'm > not sure about other platforms or SqueakJS. > > http://wiki.squeak.org/squeak/558 > > Dave From lewis at mail.msen.com Tue May 12 23:05:31 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 12 23:05:34 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <20150512221709.GA30292@shell.msen.com> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> <1E7F613D-8AEF-488C-A23B-E1F7C6C26131@rowledge.org> <20150512221709.GA30292@shell.msen.com> Message-ID: <20150512230531.GA36622@shell.msen.com> On Tue, May 12, 2015 at 06:17:09PM -0400, David T. Lewis wrote: > On Tue, May 12, 2015 at 10:27:20AM -0700, tim Rowledge wrote: > > I love the idea of well-integrated expressions etc being available for string handling and in tools. The tricky bit is that ?well-integrated?. > > > > If at all possible it should be done without any extra primitives. Unless we have a convincing use case for such string handling needing to be frequently done and very fast I don?t see much value in adding more C code. With Cog and SISTA making the system so much faster we have to consider the possibility that doing all the marshalling, converting, stack fapping, c-code calling, returning, re-converting may take more time than leaving it to Smalltalk. > > I suppose the counter-argument would be that using a standard library guarantees correct results. Except of course we have a lot of experience with supposedly standard libraries being utterly screwed. Jpeg libraries, anyone? ALSA? > > > > As for the actual expression grammar, I imagine most people would be assuming the unix regexp form which has the advantage that a lot of people are familiar with it. And the disadvantage that a very large number of people are not. > > > > There are two distict packages. > > The package at www.squeaksource.com/Regex is the Vassili Bykov implementation. > It requires no plugin support or special primitives. > > -- Regular Expression Matcher v 1.1 (C) 1996, 1999 Vassili Bykov > -- See `documentation' protocol of RxParser class for user's guide. > > The PCRE package is Andrew Greenberg's Perl compatible regular expressions. > This uses the RePlugin plugin that can be found in the VMMaker package. > RePlugin is an internal plugin in the Unix VMs (interpreter/cog/spur), I'm > not sure about other platforms or SqueakJS. > > http://wiki.squeak.org/squeak/558 > Actually there are probably more than just two. SqueakMap also has BRegexp: Description: BRegexp is Perl5 compatible regular expression library for Squeak. -Supports multilingualized Squeak. -Supports only Windows environment. Home page: http://kminami.fc2web.com/Squeak/Goodies/BRegexp/index.html SqueakMap has the Andrew Greenberg PCRE as "Regular Expression Plugin" which seems to load despite an error that pops up in the SAR postscript processing. I do not see an entry in SqueakMap for the Vassili Bykov Regex package. I am fairly sure that regex enthusiasts will have excellent reasons for favoring the Perl compatible PCRE in some cases (fast, powerful, well documented), and equally excellent reasons to favor the Vassily Bykov implementation in other cases (portable, all Smalltalk, works in SqueakJS). So it seems to me that both of these excellent packages deserve good entries in SqueakMap to make them easy to find, and easy to load in the latest Squeak images. If that is done, then I cannot think of any reason that either one of them would need to be maintained within trunk. Or to say it another way: If these packages are not important enough to make them easily loadable from SqueakMap, then they are not very important. If they are not very important, then we should not put them into trunk. So please make them loadable :-) Dave From leves at elte.hu Wed May 13 00:51:41 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 13 00:52:12 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <20150512230531.GA36622@shell.msen.com> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> <1E7F613D-8AEF-488C-A23B-E1F7C6C26131@rowledge.org> <20150512221709.GA30292@shell.msen.com> <20150512230531.GA36622@shell.msen.com> Message-ID: On Tue, 12 May 2015, David T. Lewis wrote: > On Tue, May 12, 2015 at 06:17:09PM -0400, David T. Lewis wrote: >> On Tue, May 12, 2015 at 10:27:20AM -0700, tim Rowledge wrote: >>> I love the idea of well-integrated expressions etc being available for string handling and in tools. The tricky bit is that ?well-integrated?. >>> >>> If at all possible it should be done without any extra primitives. Unless we have a convincing use case for such string handling needing to be frequently done and very fast I don?t see much value in adding more C code. With Cog and SISTA making the system so much faster we have to consider the possibility that doing all the marshalling, converting, stack fapping, c-code calling, returning, re-converting may take more time than leaving it to Smalltalk. >>> I suppose the counter-argument would be that using a standard library guarantees correct results. Except of course we have a lot of experience with supposedly standard libraries being utterly screwed. Jpeg libraries, anyone? ALSA? >>> >>> As for the actual expression grammar, I imagine most people would be assuming the unix regexp form which has the advantage that a lot of people are familiar with it. And the disadvantage that a very large number of people are not. >>> >> >> There are two distict packages. >> >> The package at www.squeaksource.com/Regex is the Vassili Bykov implementation. >> It requires no plugin support or special primitives. >> >> -- Regular Expression Matcher v 1.1 (C) 1996, 1999 Vassili Bykov >> -- See `documentation' protocol of RxParser class for user's guide. >> >> The PCRE package is Andrew Greenberg's Perl compatible regular expressions. >> This uses the RePlugin plugin that can be found in the VMMaker package. >> RePlugin is an internal plugin in the Unix VMs (interpreter/cog/spur), I'm >> not sure about other platforms or SqueakJS. >> >> http://wiki.squeak.org/squeak/558 >> > > Actually there are probably more than just two. SqueakMap also has BRegexp: > > Description: > BRegexp is Perl5 compatible regular expression library for Squeak. > -Supports multilingualized Squeak. > -Supports only Windows environment. > > Home page: > http://kminami.fc2web.com/Squeak/Goodies/BRegexp/index.html > > SqueakMap has the Andrew Greenberg PCRE as "Regular Expression Plugin" > which seems to load despite an error that pops up in the SAR postscript > processing. > > I do not see an entry in SqueakMap for the Vassili Bykov Regex package. > > I am fairly sure that regex enthusiasts will have excellent reasons for > favoring the Perl compatible PCRE in some cases (fast, powerful, well > documented), and equally excellent reasons to favor the Vassily Bykov > implementation in other cases (portable, all Smalltalk, works in SqueakJS). > > So it seems to me that both of these excellent packages deserve good > entries in SqueakMap to make them easy to find, and easy to load in > the latest Squeak images. If that is done, then I cannot think of any > reason that either one of them would need to be maintained within trunk. If the goal is to use regular expressions in Trunk, then those packages have to be in Trunk, even if they are not maintained there. Levente > > Or to say it another way: If these packages are not important enough to > make them easily loadable from SqueakMap, then they are not very important. > If they are not very important, then we should not put them into trunk. > So please make them loadable :-) > > Dave > > > From leves at elte.hu Wed May 13 01:02:33 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 13 01:02:58 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> Message-ID: On Tue, 12 May 2015, Hans-Martin Mosner wrote: > Am 12.05.2015 17:07, schrieb Levente Uzonyi: >> Definitely. I've been playing with the idea - while I was working on >> my still unreleased DNS package - but I came to the conclusion that >> the VM side has to be cleaned first. >> The plugin should use the platform's support library, instead of some >> ~10 years old version. > Please, no! It's much easier to work with some old library that has > consistent behaviour everywhere than it is to find and work around the > differences between platform libraries e.g. on Windows, Linux, and some > regular UNIX variant. At work I need to do that with VA Smalltalk code page > conversion (UTF-8 to ISO8859L1 and back) - code that works on the client > doesn't work on the server, so there's a special case and workaround needed > to get everything right. > The only acceptable option if you really want to use an external library > would be to include a standard regex C library with well-defined > functionality in the VM. Are you saying that the PCRE library behaves differently on different platforms? Levente > > Cheers, > Hans-Martin > > From ron at usmedrec.com Wed May 13 04:22:55 2015 From: ron at usmedrec.com (Ron Teitelbaum) Date: Wed May 13 04:22:56 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <8468E841-F556-4414-9763-B2A41C1E322F@rowledge.org> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> <8468E841-F556-4414-9763-B2A41C1E322F@rowledge.org> Message-ID: <054d01d08d34$7d0f12a0$772d37e0$@usmedrec.com> I guess my comment was more like, if you funded the creation of raspberry pi with the promise of Scratch ... More a joke then anything serious. I know it runs on Raspberry Pi http://news.squeak.org/2013/04/08/girls-for-rasberry-pi/ . Ron -----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] On Behalf Of tim Rowledge Sent: Tuesday, May 12, 2015 6:09 PM To: The general-purpose Squeak developers list Subject: Re: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch On 12-05-2015, at 11:33 AM, Bert Freudenberg wrote: > > Whatever its flaws, it's yet another platform shipping Squeak by default, so I thought that we might capitalize on that while it's in the news. No argument there. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: PIC: Permute Instruction Codes From nicolas.cellier.aka.nice at gmail.com Wed May 13 06:23:25 2015 From: nicolas.cellier.aka.nice at gmail.com (Nicolas Cellier) Date: Wed May 13 06:23:28 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> Message-ID: Note that at a time when I thought that VB-Regex would be a good candidate for inclusion in trunk, I put some updates in the inbox backporting some corrections that happened in Visualworks or Pharo branches http://source.squeak.org/inbox/VB-Regex-nice.20.mcz The Pharo version has evolved since with more functionalities... 2015-05-13 3:02 GMT+02:00 Levente Uzonyi : > On Tue, 12 May 2015, Hans-Martin Mosner wrote: > > Am 12.05.2015 17:07, schrieb Levente Uzonyi: >> >>> Definitely. I've been playing with the idea - while I was working on >>> my still unreleased DNS package - but I came to the conclusion that >>> the VM side has to be cleaned first. >>> The plugin should use the platform's support library, instead of some >>> ~10 years old version. >>> >> Please, no! It's much easier to work with some old library that has >> consistent behaviour everywhere than it is to find and work around the >> differences between platform libraries e.g. on Windows, Linux, and some >> regular UNIX variant. At work I need to do that with VA Smalltalk code page >> conversion (UTF-8 to ISO8859L1 and back) - code that works on the client >> doesn't work on the server, so there's a special case and workaround needed >> to get everything right. >> The only acceptable option if you really want to use an external library >> would be to include a standard regex C library with well-defined >> functionality in the VM. >> > > Are you saying that the PCRE library behaves differently on different > platforms? > > Levente > > >> Cheers, >> Hans-Martin >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/306452af/attachment.htm From lecteur at zogotounga.net Wed May 13 07:22:15 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Wed May 13 07:22:15 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: <55510971.3070002@zogotounga.net> References: <55510971.3070002@zogotounga.net> Message-ID: <5552FBA7.6060307@zogotounga.net> Hello, Still no luck with SqueakMap. Uploading appears broken, I cannot update muO there. It seems there has been no activity the last month, so I guess this is a bug in the server side. Could someone have a look ? I don't know who is maintaining SqueakMap. Stef From commits at source.squeak.org Wed May 13 11:54:32 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 13 11:54:33 2015 Subject: [squeak-dev] The Inbox: HelpSystem-Core-kfr.75.mcz Message-ID: A new version of HelpSystem-Core was added to project The Inbox: http://source.squeak.org/inbox/HelpSystem-Core-kfr.75.mcz ==================== Summary ==================== Name: HelpSystem-Core-kfr.75 Author: kfr Time: 13 May 2015, 1:52:38.849 pm UUID: 5b487f7f-b174-5343-894a-aff28511d4fa Ancestors: HelpSystem-Core-mt.74 HelpBrowser>>accept: changed so it works. The changed topic is compiled but the current topic loaded in the HelpBrowser is not updated =============== Diff against HelpSystem-Core-mt.74 =============== Item was changed: ----- Method: HelpBrowser>>accept: (in category 'actions') ----- accept: text "Accept edited text. Compile it into a HelpTopic" + | code topicClass topicMethod updatedTopic | + "true ifTrue:[^self inform: 'Not implemented yet.', String cr, 'Make new help pages in the browser for the time being']." + (self find: (self currentTopic contents copyFrom: 1 to: 20)) asArray + ifNotEmpty: [:refs | - | code topicClass topicMethod | - true ifTrue:[^self inform: 'Not implemented yet.', String cr, 'Make new help pages in the browser for the time being']. - (self find: self topic contents) asArray ifNotEmpty: [:refs | topicClass := refs first actualClass theNonMetaClass. topicMethod := refs first selector]. code := String streamContents:[:s| s nextPutAll: topicMethod. s crtab; nextPutAll: '"This method was automatically generated. Edit it using:"'. s crtab; nextPutAll: '"', self name,' edit: ', topicMethod storeString,'"'. s crtab; nextPutAll: '^HelpTopic'. s crtab: 2; nextPutAll: 'title: ', currentTopic title storeString. s crtab: 2; nextPutAll: 'contents: '. s cr; nextPutAll: (String streamContents:[:c| c nextChunkPutWithStyle: text]) storeString. s nextPutAll:' readStream nextChunkText'. ]. + updatedTopic := topicClass class - topicClass class compile: code classified: ((topicClass class organization categoryOfElement: topicMethod) ifNil:['pages']). + - self flag: #fixme. "mt: Update will not work because the topic builder eagerly cached all the contents and lost track of its origins. We need to get rid of the topic builders and create topic contents lazily resp. live." + self currentTopic: updatedTopic. - self changed: #toplevelTopics.. self changed: #currentTopic. self changed: #topicContents. ! From hmm at heeg.de Wed May 13 11:57:18 2015 From: hmm at heeg.de (Hans-Martin Mosner) Date: Wed May 13 11:57:28 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> Message-ID: <9bc61eee8812a77e41e90d1cb6e8575f@heeg.de> Am 13.05.2015 03:02, schrieb Levente Uzonyi: > On Tue, 12 May 2015, Hans-Martin Mosner wrote: > >> Am 12.05.2015 17:07, schrieb Levente Uzonyi: ... >>> The plugin should use the platform's support library, instead of some >>> ~10 years old version. >> Please, no! It's much easier to work with some old library that has >> consistent behaviour everywhere than it is to find and work around the >> differences between platform libraries e.g. on Windows, Linux, and >> some regular UNIX variant. At work I need to do that with VA Smalltalk >> code page conversion (UTF-8 to ISO8859L1 and back) - code that works >> on the client doesn't work on the server, so there's a special case >> and workaround needed to get everything right. >> The only acceptable option if you really want to use an external >> library would be to include a standard regex C library with >> well-defined functionality in the VM. > > Are you saying that the PCRE library behaves differently on different > platforms? > Nope, PCRE should behave consistently across platforms if the same version is installed on those platforms (although I'd be somewhat unsure about its handling of line ending conventions and unicode/different character sets on different platforms.) But I was responding to "platform's support library" which might be anything from PCRE through some POSIX compatible regex (from the GNU C library or some other implementation) to anything else that might be there (see http://unixpapa.com/incnote/regex.html for a list of possibilities). Cheers, Hans-Martin From Das.Linux at gmx.de Wed May 13 12:04:01 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed May 13 12:04:05 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> Message-ID: <8FED8B52-DB9B-4CF5-A6B0-0A34551DAA28@gmx.de> On 13.05.2015, at 08:23, Nicolas Cellier wrote: > Note that at a time when I thought that VB-Regex would be a good candidate for inclusion in trunk, > I put some updates in the inbox backporting some corrections that happened in Visualworks or Pharo branches > http://source.squeak.org/inbox/VB-Regex-nice.20.mcz > > The Pharo version has evolved since with more functionalities... Any reason not to include that version? (whether now[1] or after the release) Best regards -Tobias [1]: but I thought we had feature freeze? > > 2015-05-13 3:02 GMT+02:00 Levente Uzonyi : > On Tue, 12 May 2015, Hans-Martin Mosner wrote: > > Am 12.05.2015 17:07, schrieb Levente Uzonyi: > Definitely. I've been playing with the idea - while I was working on > my still unreleased DNS package - but I came to the conclusion that > the VM side has to be cleaned first. > The plugin should use the platform's support library, instead of some > ~10 years old version. > Please, no! It's much easier to work with some old library that has consistent behaviour everywhere than it is to find and work around the differences between platform libraries e.g. on Windows, Linux, and some regular UNIX variant. At work I need to do that with VA Smalltalk code page conversion (UTF-8 to ISO8859L1 and back) - code that works on the client doesn't work on the server, so there's a special case and workaround needed to get everything right. > The only acceptable option if you really want to use an external library would be to include a standard regex C library with well-defined functionality in the VM. > > Are you saying that the PCRE library behaves differently on different platforms? > > Levente > > > Cheers, > Hans-Martin > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/3fbdec27/attachment.htm From lewis at mail.msen.com Wed May 13 12:04:23 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed May 13 12:04:26 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: <5552FBA7.6060307@zogotounga.net> References: <55510971.3070002@zogotounga.net> <5552FBA7.6060307@zogotounga.net> Message-ID: <20150513120423.GA62166@shell.msen.com> Copying the box-admins list: On Wed, May 13, 2015 at 09:22:15AM +0200, St??phane Rollandin wrote: > Hello, > > Still no luck with SqueakMap. Uploading appears broken, I cannot update > muO there. It seems there has been no activity the last month, so I > guess this is a bug in the server side. > > Could someone have a look ? I don't know who is maintaining SqueakMap. > > > Stef From lewis at mail.msen.com Wed May 13 12:07:51 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed May 13 12:07:53 2015 Subject: [squeak-dev] Re: The Trunk: Tools-mt.622.mcz In-Reply-To: <1431456184473-4826067.post@n4.nabble.com> References: <1431180976415-4825440.post@n4.nabble.com> <1431418978931-4825935.post@n4.nabble.com> <57023.136.2.1.104.1431453572.squirrel@webmail.msen.com> <1431456184473-4826067.post@n4.nabble.com> Message-ID: <20150513120751.GB62166@shell.msen.com> On Tue, May 12, 2015 at 11:43:04AM -0700, marcel.taeumel wrote: > I also plan to add an abstraction for my Widgets project [1] to support > ToolBuilder-based tools. :) Excellent :-) Dave > > Best, > Marcel > > [1] https://github.com/hpi-swa/widgets > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Tools-mt-622-mcz-tp4825209p4826067.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Wed May 13 13:10:22 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 13 13:27:00 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: References: Message-ID: <1431522622870-4826168.post@n4.nabble.com> This can only work for ClassBasedHelpTopics because those have contents encoded in methods and classes (being subclasses of CustomHelp). Can you add a check for that? Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826168.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Wed May 13 13:18:13 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 13 13:34:48 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: <1431522622870-4826168.post@n4.nabble.com> References: <1431522622870-4826168.post@n4.nabble.com> Message-ID: <1431523093810-4826172.post@n4.nabble.com> The pages are cached so they can be found and navigated to from the search results. We could think about some cache invalidation for changed pages. Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826172.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Wed May 13 13:20:31 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 13 13:37:06 2015 Subject: [squeak-dev] Re: Support Regular Expressions in Trunk In-Reply-To: <8FED8B52-DB9B-4CF5-A6B0-0A34551DAA28@gmx.de> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> <8FED8B52-DB9B-4CF5-A6B0-0A34551DAA28@gmx.de> Message-ID: <1431523231108-4826173.post@n4.nabble.com> Sure. This discussion is beyond 4.6/5.0 :) Best, Marcel -- View this message in context: http://forum.world.st/Support-Regular-Expressions-in-Trunk-tp4825937p4826173.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From asqueaker at gmail.com Wed May 13 15:31:09 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed May 13 15:31:12 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: <5552FBA7.6060307@zogotounga.net> References: <55510971.3070002@zogotounga.net> <5552FBA7.6060307@zogotounga.net> Message-ID: Hi St?phane, I checked the server earlier and everything seems to be running fine. Now I just did a test upload from the web page and it worked fine. How large is the file that you're trying to upload? On Wed, May 13, 2015 at 2:22 AM, St?phane Rollandin wrote: > Hello, > > Still no luck with SqueakMap. Uploading appears broken, I cannot update muO > there. It seems there has been no activity the last month, so I guess this > is a bug in the server side. > > Could someone have a look ? I don't know who is maintaining SqueakMap. > > > Stef > From eliot.miranda at gmail.com Wed May 13 15:43:29 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed May 13 15:43:33 2015 Subject: [squeak-dev] New CogVMs available Message-ID: at http://www.mirandabanda.org/files/Cog/VM/VM.r3336/. CogVM binaries as per VMMaker.oscog-eem.1299/r3336 Clarify how to specify variadic primitives in the Cogit's primitive table initializer (it had confused me enough to cause a regression). Fix the regression in genPrmitiveClass. Implement the stream primtiives using genFastPrimFail which should speed up the stream prims noticeably. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/c7d6b255/attachment.htm From Das.Linux at gmx.de Wed May 13 16:02:20 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed May 13 16:02:45 2015 Subject: [squeak-dev] Re: [Vm-dev] New CogVMs available In-Reply-To: References: Message-ID: <681D54E0-1928-4697-B6CC-FD79C42EF0E5@gmx.de> ..and updated on CI, Job running at: http://build.squeak.org/job/SqueakTrunk/1479/consoleFull On 13.05.2015, at 17:43, Eliot Miranda wrote: > at http://www.mirandabanda.org/files/Cog/VM/VM.r3336/. > > CogVM binaries as per VMMaker.oscog-eem.1299/r3336 > > Clarify how to specify variadic primitives in the Cogit's primitive table > initializer (it had confused me enough to cause a regression). > > Fix the regression in genPrmitiveClass. > > Implement the stream primtiives using genFastPrimFail > which should speed up the stream prims noticeably. From asqueaker at gmail.com Wed May 13 16:05:53 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed May 13 16:05:55 2015 Subject: [squeak-dev] release progress Message-ID: Now that we're in a feature freeze, we can focus on the essentials of getting the release out but we need to get up-to-date Cog and Spur images made and accessible. So what is the final answer regarding "keep local" or "keep remote" when updating Spur image? Eliot, is this a a good time to upload another Spur image to mirandabanda? From Das.Linux at gmx.de Wed May 13 16:45:38 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed May 13 16:45:42 2015 Subject: [squeak-dev] Re: [Vm-dev] New CogVMs available In-Reply-To: <681D54E0-1928-4697-B6CC-FD79C42EF0E5@gmx.de> References: <681D54E0-1928-4697-B6CC-FD79C42EF0E5@gmx.de> Message-ID: <022B98CA-CC8D-4757-84CA-03F16CC2ACEC@gmx.de> On 13.05.2015, at 18:02, Tobias Pape wrote: > ..and updated on CI, > Job running at: http://build.squeak.org/job/SqueakTrunk/1479/consoleFull The build also errored with the dnu that is a suspected stack corruption bug (not verified) > > On 13.05.2015, at 17:43, Eliot Miranda wrote: > >> at http://www.mirandabanda.org/files/Cog/VM/VM.r3336/. >> >> CogVM binaries as per VMMaker.oscog-eem.1299/r3336 >> >> Clarify how to specify variadic primitives in the Cogit's primitive table >> initializer (it had confused me enough to cause a regression). >> >> Fix the regression in genPrmitiveClass. >> >> Implement the stream primtiives using genFastPrimFail >> which should speed up the stream prims noticeably. From commits at source.squeak.org Wed May 13 16:54:10 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 13 16:54:11 2015 Subject: [squeak-dev] The Inbox: HelpSystem-Core-kfr.76.mcz Message-ID: A new version of HelpSystem-Core was added to project The Inbox: http://source.squeak.org/inbox/HelpSystem-Core-kfr.76.mcz ==================== Summary ==================== Name: HelpSystem-Core-kfr.76 Author: kfr Time: 13 May 2015, 6:53:53.29 pm UUID: fbad033b-7c29-0748-bdb5-02a02dff4cf7 Ancestors: HelpSystem-Core-kfr.75 Added a check/ bail out for non editable help topics =============== Diff against HelpSystem-Core-kfr.75 =============== Item was changed: ----- Method: HelpBrowser>>accept: (in category 'actions') ----- accept: text "Accept edited text. Compile it into a HelpTopic" | code topicClass topicMethod updatedTopic | "true ifTrue:[^self inform: 'Not implemented yet.', String cr, 'Make new help pages in the browser for the time being']." (self find: (self currentTopic contents copyFrom: 1 to: 20)) asArray + ifNotEmpty: [:refs | - ifNotEmpty: [:refs | topicClass := refs first actualClass theNonMetaClass. topicMethod := refs first selector]. + topicClass = nil ifTrue:[^self inform: 'This help topic can not be edited here']. - code := String streamContents:[:s| s nextPutAll: topicMethod. s crtab; nextPutAll: '"This method was automatically generated. Edit it using:"'. s crtab; nextPutAll: '"', self name,' edit: ', topicMethod storeString,'"'. s crtab; nextPutAll: '^HelpTopic'. s crtab: 2; nextPutAll: 'title: ', currentTopic title storeString. s crtab: 2; nextPutAll: 'contents: '. s cr; nextPutAll: (String streamContents:[:c| c nextChunkPutWithStyle: text]) storeString. s nextPutAll:' readStream nextChunkText'. ]. updatedTopic := topicClass class compile: code classified: ((topicClass class organization categoryOfElement: topicMethod) ifNil:['pages']). self flag: #fixme. "mt: Update will not work because the topic builder eagerly cached all the contents and lost track of its origins. We need to get rid of the topic builders and create topic contents lazily resp. live." self currentTopic: updatedTopic. self changed: #toplevelTopics.. self changed: #currentTopic. self changed: #topicContents. ! From karlramberg at gmail.com Wed May 13 16:56:34 2015 From: karlramberg at gmail.com (karl ramberg) Date: Wed May 13 16:56:37 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: <1431522622870-4826168.post@n4.nabble.com> References: <1431522622870-4826168.post@n4.nabble.com> Message-ID: I added a basic way that give info that a help topic is not editable. Karl On Wed, May 13, 2015 at 3:10 PM, marcel.taeumel wrote: > This can only work for ClassBasedHelpTopics because those have contents > encoded in methods and classes (being subclasses of CustomHelp). Can you > add > a check for that? > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826168.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/15b5a4d4/attachment.htm From karlramberg at gmail.com Wed May 13 16:57:50 2015 From: karlramberg at gmail.com (karl ramberg) Date: Wed May 13 16:57:52 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: <1431523093810-4826172.post@n4.nabble.com> References: <1431522622870-4826168.post@n4.nabble.com> <1431523093810-4826172.post@n4.nabble.com> Message-ID: Yes, reloading of topics would be good. I'm not quite sure how to do it yet. Karl On Wed, May 13, 2015 at 3:18 PM, marcel.taeumel wrote: > The pages are cached so they can be found and navigated to from the search > results. We could think about some cache invalidation for changed pages. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826172.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/45bee21a/attachment.htm From leves at elte.hu Wed May 13 17:25:09 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 13 17:25:14 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: <9bc61eee8812a77e41e90d1cb6e8575f@heeg.de> References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> <9bc61eee8812a77e41e90d1cb6e8575f@heeg.de> Message-ID: On Wed, 13 May 2015, Hans-Martin Mosner wrote: > Am 13.05.2015 03:02, schrieb Levente Uzonyi: >> On Tue, 12 May 2015, Hans-Martin Mosner wrote: >> >>> Am 12.05.2015 17:07, schrieb Levente Uzonyi: > ... >>>> The plugin should use the platform's support library, instead of some >>>> ~10 years old version. >>> Please, no! It's much easier to work with some old library that has >>> consistent behaviour everywhere than it is to find and work around the >>> differences between platform libraries e.g. on Windows, Linux, and some >>> regular UNIX variant. At work I need to do that with VA Smalltalk code >>> page conversion (UTF-8 to ISO8859L1 and back) - code that works on the >>> client doesn't work on the server, so there's a special case and >>> workaround needed to get everything right. >>> The only acceptable option if you really want to use an external library >>> would be to include a standard regex C library with well-defined >>> functionality in the VM. >> >> Are you saying that the PCRE library behaves differently on different >> platforms? >> > > Nope, PCRE should behave consistently across platforms if the same version is > installed on those platforms (although I'd be somewhat unsure about its > handling of line ending conventions and unicode/different character sets on > different platforms.) > But I was responding to "platform's support library" which might be anything > from PCRE through some POSIX compatible regex (from the GNU C library or some > other implementation) to anything else that might be there (see > http://unixpapa.com/incnote/regex.html for a list of possibilities). The RePlugin is a wrapper for the PCRE library, so what I'm saying is that we should use the system's installed PCRE library (or statically link an up-to-date version), instead of a really old fork of it. The PCRE API won't change anymore, since PCRE2 is here. Levente > > Cheers, > Hans-Martin > > From lewis at mail.msen.com Wed May 13 17:35:00 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed May 13 17:35:03 2015 Subject: [squeak-dev] Support Regular Expressions in Trunk In-Reply-To: References: <1431419474638-4825937.post@n4.nabble.com> <39a6eed1c32c3087e6d5630b65d58b1e@heeg.de> <9bc61eee8812a77e41e90d1cb6e8575f@heeg.de> Message-ID: <6846.136.2.1.105.1431538500.squirrel@webmail.msen.com> > On Wed, 13 May 2015, Hans-Martin Mosner wrote: > >> Am 13.05.2015 03:02, schrieb Levente Uzonyi: >>> On Tue, 12 May 2015, Hans-Martin Mosner wrote: >>> >>>> Am 12.05.2015 17:07, schrieb Levente Uzonyi: >> ... >>>>> The plugin should use the platform's support library, instead of some >>>>> ~10 years old version. >>>> Please, no! It's much easier to work with some old library that has >>>> consistent behaviour everywhere than it is to find and work around the >>>> differences between platform libraries e.g. on Windows, Linux, and >>>> some >>>> regular UNIX variant. At work I need to do that with VA Smalltalk code >>>> page conversion (UTF-8 to ISO8859L1 and back) - code that works on the >>>> client doesn't work on the server, so there's a special case and >>>> workaround needed to get everything right. >>>> The only acceptable option if you really want to use an external >>>> library >>>> would be to include a standard regex C library with well-defined >>>> functionality in the VM. >>> >>> Are you saying that the PCRE library behaves differently on different >>> platforms? >>> >> >> Nope, PCRE should behave consistently across platforms if the same >> version is >> installed on those platforms (although I'd be somewhat unsure about its >> handling of line ending conventions and unicode/different character sets >> on >> different platforms.) >> But I was responding to "platform's support library" which might be >> anything >> from PCRE through some POSIX compatible regex (from the GNU C library or >> some >> other implementation) to anything else that might be there (see >> http://unixpapa.com/incnote/regex.html for a list of possibilities). > > The RePlugin is a wrapper for the PCRE library, so what I'm saying is that > we should use the system's installed PCRE library (or statically link an > up-to-date version), instead of a really old fork of it. > The PCRE API won't change anymore, since PCRE2 is here. > Yes, this is important for Linux distro maintainers. http://bugs.squeak.org/view.php?id=7539 Dave From ron at usmedrec.com Wed May 13 17:46:14 2015 From: ron at usmedrec.com (Ron Teitelbaum) Date: Wed May 13 17:46:14 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <054d01d08d34$7d0f12a0$772d37e0$@usmedrec.com> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> <8468E841-F556-4414-9763-B2A41C1E322F@rowledge.org> <054d01d08d34$7d0f12a0$772d37e0$@usmedrec.com> Message-ID: <06d101d08da4$b59b4830$20d1d890$@usmedrec.com> I've received a number of comments that my joke wasn't well received. I've deleted it. Sorry for the noise. Ron -----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] On Behalf Of Ron Teitelbaum Sent: Wednesday, May 13, 2015 12:23 AM To: 'The general-purpose Squeak developers list' Subject: RE: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch I guess my comment was more like, if you funded the creation of raspberry pi with the promise of Scratch ... More a joke then anything serious. I know it runs on Raspberry Pi http://news.squeak.org/2013/04/08/girls-for-rasberry-pi/ . Ron -----Original Message----- From: squeak-dev-bounces@lists.squeakfoundation.org [mailto:squeak-dev-bounces@lists.squeakfoundation.org] On Behalf Of tim Rowledge Sent: Tuesday, May 12, 2015 6:09 PM To: The general-purpose Squeak developers list Subject: Re: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch On 12-05-2015, at 11:33 AM, Bert Freudenberg wrote: > > Whatever its flaws, it's yet another platform shipping Squeak by > default, so I thought that we might capitalize on that while it's in the news. No argument there. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Strange OpCodes: PIC: Permute Instruction Codes From Marcel.Taeumel at hpi.de Wed May 13 17:37:48 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 13 17:54:26 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: References: <1431522622870-4826168.post@n4.nabble.com> <1431523093810-4826172.post@n4.nabble.com> Message-ID: <1431538668657-4826254.post@n4.nabble.com> We could add the notion of a #parent. Then each topic could tell its parent that it has changed. The parent topic then just updates the cache/subtopics. Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826254.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Wed May 13 18:24:26 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Wed May 13 18:24:28 2015 Subject: [squeak-dev] release progress In-Reply-To: References: Message-ID: On Wed, May 13, 2015 at 9:05 AM, Chris Muller wrote: > Now that we're in a feature freeze, we can focus on the essentials of > getting the release out but we need to get up-to-date Cog and Spur > images made and accessible. So what is the final answer regarding > "keep local" or "keep remote" when updating Spur image? Eliot, is > this a a good time to upload another Spur image to mirandabanda? > Yes. I'll be checking that the image updates correctly as soon as possible. But it won't be until tomorrow at the earliest. I've a few essential tasks to do before that. I will also try and make a 64-bit image available, and a 64-bit linux Stack VM. Just for people to play with; it's in no way supported, but is usable. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/551379f5/attachment.htm From karlramberg at gmail.com Wed May 13 18:25:04 2015 From: karlramberg at gmail.com (karl ramberg) Date: Wed May 13 18:25:06 2015 Subject: [squeak-dev] release progress In-Reply-To: References: Message-ID: How about: Keep local Install remote Karl On Wed, May 13, 2015 at 6:05 PM, Chris Muller wrote: > Now that we're in a feature freeze, we can focus on the essentials of > getting the release out but we need to get up-to-date Cog and Spur > images made and accessible. So what is the final answer regarding > "keep local" or "keep remote" when updating Spur image? Eliot, is > this a a good time to upload another Spur image to mirandabanda? > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/6ac5afe3/attachment-0001.htm From Marcel.Taeumel at hpi.de Wed May 13 19:38:29 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 13 19:55:07 2015 Subject: [squeak-dev] Re: Keep Local vs Keep Remote when merging In-Reply-To: <2CF10EB5-6B62-4E25-BFBD-17DE489F4F4B@rowledge.org> References: <20150508021949.GA7296@shell.msen.com> <2B79F4F2-C94B-41FC-B7BF-BB7FE09DA7C5@gmail.com> <86343CE3-ED79-4251-83BD-217F268BE890@freudenbergs.de> <2CF10EB5-6B62-4E25-BFBD-17DE489F4F4B@rowledge.org> Message-ID: <1431545909428-4826266.post@n4.nabble.com> If I merge code from a file or repository, I think of data flowing from the outside into my environment/image (even onto my local code). So the question is whether to modify local code or not. Nothing will ever happen to the remote code, so "keep remote" makes no sense. *Both* buttons should either describe what happens to local code or what happens with remote code. Here are some ideas: [Keep local] and [Update local] [Install remote] and [Ignore remote] Best, Marcel -- View this message in context: http://forum.world.st/automated-way-to-delete-specific-trunk-packages-tp4825180p4826266.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From casimiro.barreto at gmail.com Wed May 13 21:25:54 2015 From: casimiro.barreto at gmail.com (Casimiro de Almeida Barreto) Date: Wed May 13 21:26:03 2015 Subject: [squeak-dev] release progress In-Reply-To: References: Message-ID: <5553C162.50505@gmail.com> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150513/93e7ebdf/signature.pgp From tim at rowledge.org Wed May 13 22:16:06 2015 From: tim at rowledge.org (tim Rowledge) Date: Wed May 13 22:16:15 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <054d01d08d34$7d0f12a0$772d37e0$@usmedrec.com> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> <32427E45-3416-4D04-B9AE-04D705315D28@freudenbergs.de> <8468E841-F556-4414-9763-B2A41C1E322F@rowledge.org> <054d01d08d34$7d0f12a0$772d37e0$@usmedrec.com> Message-ID: On 12-05-2015, at 9:22 PM, Ron Teitelbaum wrote: > I guess my comment was more like, if you funded the creation of raspberry pi > with the promise of Scratch ? Jokes are really hard to make effectively online with text. Sometimes what would be hilarious in person just sounds awful in text with no further context. I blame Fred. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim this blank intentionally left spaced From commits at source.squeak.org Thu May 14 01:14:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 14 01:14:15 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.634.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.634.mcz ==================== Summary ==================== Name: Collections.spur-ul.634 Author: eem Time: 13 May 2015, 6:13:28.985 pm UUID: c9b09516-9167-494a-8dd7-3e0268f68686 Ancestors: Collections-ul.634, Collections.spur-ul.633 Collections-ul.634 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Revert the workaround from Collections-ul.633. =============== Diff against Collections-ul.634 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 14 May 2015 1:14:13.244 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 14 01:14:44 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 14 01:14:47 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.635.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.635.mcz ==================== Summary ==================== Name: Collections.spur-mt.635 Author: eem Time: 13 May 2015, 6:13:31.169 pm UUID: 024683bd-996d-483b-a731-4296aae8945c Ancestors: Collections-mt.635, Collections.spur-ul.634 Collections-mt.635 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Some debug code removed from html readwriter.. =============== Diff against Collections-mt.635 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 14 May 2015 1:14:43.428 am VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Thu May 14 01:15:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 14 01:15:14 2015 Subject: [squeak-dev] The Trunk: System.spur-ul.737.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-ul.737.mcz ==================== Summary ==================== Name: System.spur-ul.737 Author: eem Time: 13 May 2015, 6:13:38.661 pm UUID: 2c2811ae-bd3a-4804-b54a-ec21d5cb1cdf Ancestors: System-ul.737, System.spur-kfr.736 System-ul.737 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 #groupBy:having -> #groupBy: =============== Diff against System-ul.737 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From jecel at merlintec.com Thu May 14 04:54:34 2015 From: jecel at merlintec.com (Jecel Assumpcao Jr.) Date: Thu May 14 04:54:49 2015 Subject: [squeak-dev] C.H.I.P. comes pre-loaded with Scratch In-Reply-To: <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> References: <6D77DF68-0CD1-44CF-92E8-92466E608510@freudenbergs.de> <31890144-10EA-461E-B6AF-35F4C6C5F753@rowledge.org> Message-ID: While calling the Raspberry Pi and the C.H.I.P. "computers" is very good marketing, it is also rather misleading. Most people would call just a box with no keyboard or monitor a "cpu" rather than a computer. And if it is just a board with components that doesn't have a box, power supply or disks (in the case of the Raspberry Pi) they would call it a "motherboard". You can see the confusion when taking into account that you can buy four of the slightly weaker C.H.I.P. for the same as just one Raspberry Pi B. But if you check the costs for complete systems then they are essentially the same and close to the price of the lowest end laptops and tablets. Having said all that, I think that the C.H.I.P. designers did a very good job. When I first saw what AllWinner was doing with the ARM a few years back this was exactly what I was looking forward to seeing. It is a pity that you still can't buy five, for example, $9 boards and hook them together into one faster computer. After all, Linux clusters are pretty mature technology by now. -- Jecel From commits at source.squeak.org Thu May 14 08:15:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 14 08:15:02 2015 Subject: [squeak-dev] The Inbox: HelpSystem-Core-kfr.77.mcz Message-ID: A new version of HelpSystem-Core was added to project The Inbox: http://source.squeak.org/inbox/HelpSystem-Core-kfr.77.mcz ==================== Summary ==================== Name: HelpSystem-Core-kfr.77 Author: kfr Time: 14 May 2015, 10:14:49.361 am UUID: b5acbf22-bb99-744b-a8b7-9fa05787ddec Ancestors: HelpSystem-Core-kfr.76 Replace a edited help topic in HelpBrowser with a new one. There is still a bug that the updated topic changes place in the topic list I'm also a little confused why there is two hierachies with the help topics in rootTopic and topLevelTopics =============== Diff against HelpSystem-Core-kfr.76 =============== Item was changed: Model subclass: #HelpBrowser + instanceVariableNames: 'rootTopic currentTopic result searchTopic topicPath toplevelTopics oldTopic' - instanceVariableNames: 'rootTopic currentTopic result searchTopic topicPath toplevelTopics' classVariableNames: 'DefaultHelpBrowser' poolDictionaries: '' category: 'HelpSystem-Core-UI'! !HelpBrowser commentStamp: 'tbn 3/8/2010 09:33' prior: 0! A HelpBrowser is used to display a hierarchy of help topics and their contents. Instance Variables rootTopic: window: treeMorph: contentMorph: rootTopic - xxxxx window - xxxxx treeMorph - xxxxx contentMorph - xxxxx ! Item was changed: ----- Method: HelpBrowser>>accept: (in category 'actions') ----- accept: text "Accept edited text. Compile it into a HelpTopic" | code topicClass topicMethod updatedTopic | - "true ifTrue:[^self inform: 'Not implemented yet.', String cr, 'Make new help pages in the browser for the time being']." (self find: (self currentTopic contents copyFrom: 1 to: 20)) asArray ifNotEmpty: [:refs | topicClass := refs first actualClass theNonMetaClass. topicMethod := refs first selector]. topicClass = nil ifTrue:[^self inform: 'This help topic can not be edited here']. code := String streamContents:[:s| s nextPutAll: topicMethod. s crtab; nextPutAll: '"This method was automatically generated. Edit it using:"'. s crtab; nextPutAll: '"', self name,' edit: ', topicMethod storeString,'"'. s crtab; nextPutAll: '^HelpTopic'. s crtab: 2; nextPutAll: 'title: ', currentTopic title storeString. s crtab: 2; nextPutAll: 'contents: '. s cr; nextPutAll: (String streamContents:[:c| c nextChunkPutWithStyle: text]) storeString. s nextPutAll:' readStream nextChunkText'. ]. + topicClass class - updatedTopic := topicClass class compile: code classified: ((topicClass class organization categoryOfElement: topicMethod) ifNil:['pages']). + updatedTopic := topicClass perform: topicMethod. + oldTopic := currentTopic. + "self inTopic: self rootTopic replaceCurrentTopicWith: updatedTopic". + self toplevelTopics do:[ :each | self inTopic: each replaceCurrentTopicWith: updatedTopic]. - - self flag: #fixme. "mt: Update will not work because the topic builder eagerly cached all the contents and lost track of its origins. We need to get rid of the topic builders and create topic contents lazily resp. live." - self currentTopic: updatedTopic. self changed: #toplevelTopics.. self changed: #currentTopic. self changed: #topicContents. ! Item was added: + ----- Method: HelpBrowser>>inTopic:replaceCurrentTopicWith: (in category 'actions') ----- + inTopic: parentTopic replaceCurrentTopicWith: aNewTopic + + parentTopic subtopics + do: [ :sub | self inTopic: parentTopic replaceSubtopic: sub with: aNewTopic]! Item was added: + ----- Method: HelpBrowser>>inTopic:replaceSubtopic:with: (in category 'actions') ----- + inTopic: parentTopic replaceSubtopic: aTopic with: aNewTopic + | i | + + (aTopic = oldTopic) + ifTrue: [ i := parentTopic subtopics indexOf: aTopic. + parentTopic subtopics at: i put: aNewTopic. ^self ]. + + aTopic subtopics + do: [ :sub | self inTopic: aTopic replaceSubtopic: sub with: aNewTopic]! From karlramberg at gmail.com Thu May 14 08:21:05 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 14 08:21:09 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: <1431538668657-4826254.post@n4.nabble.com> References: <1431522622870-4826168.post@n4.nabble.com> <1431523093810-4826172.post@n4.nabble.com> <1431538668657-4826254.post@n4.nabble.com> Message-ID: Hi, I made an attempt at updating the topic in place. There are some issues with it still, the edited topic changes place in the topic list in the treeMorph. I'm also a little confused why we have two hierarchies ( rootTopic and topLevelTopics) with the help topics. It would seem that one would be enough ? On Wed, May 13, 2015 at 7:37 PM, marcel.taeumel wrote: > We could add the notion of a #parent. Then each topic could tell its parent > that it has changed. The parent topic then just updates the > cache/subtopics. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826254.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/e381d243/attachment.htm From Marcel.Taeumel at hpi.de Thu May 14 09:02:09 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 14 09:18:53 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: References: <1431522622870-4826168.post@n4.nabble.com> <1431523093810-4826172.post@n4.nabble.com> <1431538668657-4826254.post@n4.nabble.com> Message-ID: <1431594129584-4826317.post@n4.nabble.com> The tree widget expects a list of "roots" but the help browser es exactly one, which is not visible but encoded in the windows title bar. Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826317.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Thu May 14 09:46:23 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 14 09:46:26 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: <1431594129584-4826317.post@n4.nabble.com> References: <1431522622870-4826168.post@n4.nabble.com> <1431523093810-4826172.post@n4.nabble.com> <1431538668657-4826254.post@n4.nabble.com> <1431594129584-4826317.post@n4.nabble.com> Message-ID: Ok Karl On Thu, May 14, 2015 at 11:02 AM, marcel.taeumel wrote: > The tree widget expects a list of "roots" but the help browser es exactly > one, which is not visible but encoded in the windows title bar. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826317.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/4011ae28/attachment.htm From lecteur at zogotounga.net Thu May 14 11:03:48 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Thu May 14 11:03:53 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: References: <55510971.3070002@zogotounga.net> <5552FBA7.6060307@zogotounga.net> Message-ID: <55548114.1030201@zogotounga.net> Le 13/05/2015 17:31, Chris Muller a ?crit : > Hi St?phane, I checked the server earlier and everything seems to be > running fine. Now I just did a test upload from the web page and it > worked fine. > > How large is the file that you're trying to upload? 3 Mb; my connexion is very slow though. Stef From bert at freudenbergs.de Thu May 14 11:24:11 2015 From: bert at freudenbergs.de (Bert Freudenberg) Date: Thu May 14 11:24:16 2015 Subject: [squeak-dev] release progress In-Reply-To: References: Message-ID: <159E8A26-7CA4-4914-AA88-3C6258D22811@freudenbergs.de> Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 4115 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/2cdab523/smime.bin From karlramberg at gmail.com Thu May 14 14:33:53 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 14 14:33:59 2015 Subject: [squeak-dev] Mail list archive woes Message-ID: The mail list archive is not very good with multi-part mails. It stores just one part and we end up with stuff like this: http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-March/182492.html and this from Bert: http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184333.html Is there some way to store all the parts ? Karl -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/69fc02cf/attachment.htm From jgr.asselin at me.com Thu May 14 15:13:10 2015 From: jgr.asselin at me.com (Raymond Asselin) Date: Thu May 14 15:13:15 2015 Subject: [squeak-dev] Cog VM problem? Message-ID: Cog.app-15.19.3336.tgz gave me a Debugger window -------------- next part -------------- A non-text attachment was scrubbed... Name: SqueakDebug.log Type: application/octet-stream Size: 11814 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/712ad20f/SqueakDebug-0001.obj -------------- next part -------------- with these artefacts This is a MauiDomainMorph -------------- next part -------------- A non-text attachment was scrubbed... Name: a MauiDomainMorph(3500).jpeg Type: image/png Size: 33553 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/712ad20f/aMauiDomainMorphaCalepinSante3500-0001.png From karlramberg at gmail.com Thu May 14 15:26:17 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 14 15:26:21 2015 Subject: [squeak-dev] Cog VM problem? In-Reply-To: References: Message-ID: You can test this workaround: SimpleBorder>>width ^width ifNil:[0] Open image with an earlier VM and modify that method so it does not return a nil. Karl On Thu, May 14, 2015 at 5:13 PM, Raymond Asselin wrote: > Cog.app-15.19.3336.tgz > gave me a Debugger window > > > > with these artefacts > This is a MauiDomainMorph > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/fc0797ed/attachment.htm From lecteur at zogotounga.net Thu May 14 15:33:45 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Thu May 14 15:33:51 2015 Subject: [squeak-dev] A little puzzle Message-ID: <5554C059.3060002@zogotounga.net> Hello all, I'm finding myself unable to implement something seemingly simple. Here is the puzzle: I want an iterator factory which, given a specific collection, produces a block taking two arguments, also blocks. One (the doBlock) tells what should be done for each element of the collection, and the other (the whileBlock) is a test allowing to abort the whole operation. So, something like this: Puzzle>>blockIterating: aCollection ^ [:doBlock :whileBlock | aCollection do: [:i | (whileBlock value: i) ifFalse: [^ self]. doBlock value: i]]. Then I could do things like the following: | block | block := Puzzle new blockIterating: (1 to: 5). block value: [:p | Transcript show: p; cr] value: [:p | p < 3] But the above fails with a 'Block cannot return' (that's the [^ self] block in the #blockIterating: method). I have attached the code; just do "Puzzle new fail". I can't find a workaround. How should I proceed to get a working iterator block ? Stef -------------- next part -------------- 'From Squeak4.5 of 10 May 2015 [latest update: #15009] on 14 May 2015 at 4:24:25 pm'! Object subclass: #Puzzle instanceVariableNames: 'block' classVariableNames: '' poolDictionaries: '' category: 'Bugs'! !Puzzle commentStamp: '' prior: 0! Puzzle new fail "doIt"! ]style[(15 7)cblack;,! !Puzzle methodsFor: 'as yet unclassified' stamp: 'spfa 5/14/2015 16:22'! blockIterating: aCollection ^ [:doBlock :whileBlock | aCollection do: [:i | (whileBlock value: i) ifFalse: [^ self]. doBlock value: i]].! ! !Puzzle methodsFor: 'as yet unclassified' stamp: 'spfa 5/14/2015 16:22'! fail block := self blockIterating: (1 to: 5). block value: [:p | Transcript show: p; cr] value: [:p | p < 3] ! ! From ma.chris.m at gmail.com Thu May 14 15:35:13 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Thu May 14 15:35:15 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: <55548114.1030201@zogotounga.net> References: <55510971.3070002@zogotounga.net> <5552FBA7.6060307@zogotounga.net> <55548114.1030201@zogotounga.net> Message-ID: the service log file has strange error message in it (below). what browser are you using? are there any special characters in the file name? Error: You must upload a file with PUT 13 May 2015 12:24:20 am VM: unix - a SmalltalkImage Image: Squeak3.8 [latest update: #6665] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeakmap Trusted Dir /home/squeakmap/secure Untrusted Dir /home/squeakmap/My Squeak SMUploadFileAction(Object)>>error: Receiver: a SMUploadFileAction Arguments and temporary variables: aString: 'You must upload a file with PUT' Receiver's instance variables: request: HttpRequest (URL=/upload/; protocol=HTTP/1.1; header=a Dictionary('con...etc... fields: nil account: nil SMUploadFileAction>>go Receiver: a SMUploadFileAction Arguments and temporary variables: s: nil Receiver's instance variables: request: HttpRequest (URL=/upload/; protocol=HTTP/1.1; header=a Dictionary('con...etc... fields: nil account: nil SMUploadFileAction(SMRemoteAction)>>response Receiver: a SMUploadFileAction Arguments and temporary variables: Receiver's instance variables: request: HttpRequest (URL=/upload/; protocol=HTTP/1.1; header=a Dictionary('con...etc... fields: nil account: nil SMSqueakMapView>>upload Receiver: a SMSqueakMapView Arguments and temporary variables: Receiver's instance variables: model: a SMSqueakMap parent: a SMRootView title: 'SqueakMap' req: HttpRequest (URL=/upload/; protocol=HTTP/1.1; header=a Dictionary('connect...etc... urlStream: a HVUrlStream urlOriginalPosition: 0 formatter: nil --- The full stack --- SMUploadFileAction(Object)>>error: SMUploadFileAction>>go SMUploadFileAction(SMRemoteAction)>>response SMSqueakMapView>>upload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SMSqueakMapView(HVTransientView)>>dispatchOn: SMSqueakMapView(HVTransientView)>>dispatch [] in SMRootView(HVRootView)>>process: {[^ view dispatch asHttpResponseTo: request]} BlockContext>>on:do: SMRootView(HVRootView)>>process: [] in SMRootView(HVRootView)>>startOn:mode: {[:request | self process: request]} BlockContext>>processHttp [] in ModSession(ComancheModule)>>processSubModules {[:module | module processHttp ifTrue: [^ true]. nil]} OrderedCollection>>do: ModSession(ComancheModule)>>subModulesDo: ModSession(ComancheModule)>>processSubModules ModSession>>processHttp [] in ModCore(ComancheModule)>>processSubModules {[:module | module processHttp ifTrue: [^ true]. nil]} OrderedCollection>>do: ModCore(ComancheModule)>>subModulesDo: ModCore(ComancheModule)>>processSubModules ModCore>>processHttp ModCore(ComancheModule)>>processHttpRequest: HttpService>>processHttpRequest: [] in HttpAdaptor>>dispatchRequest: {[self class current: self. HttpRequest current: request. self target proce...]} HttpService>>handleDispatchErrorsIn: HttpAdaptor>>dispatchRequest: [] in HttpAdaptor>>beginConversation {[response := self dispatchRequest: request. self addConnectionHeaders: re...]} BlockContext>>on:do: BlockContext>>valueWithBindingsContext: BlockContext>>valueWithBindings: BindingsAccessor>>clamp: [] in HttpAdaptor>>beginConversation {[Bindings clamp: [response := self dispatchRequest: request. self a...]} BlockContext>>ifCurtailed: HttpAdaptor>>beginConversation HttpAdaptor class>>readAndWriteTo:service: HttpAdaptor class>>readAndWriteToSocket:service: HttpService>>serve: [] in HttpService(TcpService)>>value: {[self serve: aSocket]} BlockContext>>on:do: BlockContext>>valueWithBindingsContext: BlockContext>>valueWithBindings: BindingsAccessor>>clamp: [] in BlockContext>>newProcessWithClampedBindings: {[Bindings clamp: self]} BlockContext>>on:do: BlockContext>>valueWithBindingsContext: BlockContext>>valueWithBindings: [] in BlockContext>>newProcessWithBindings: {[self valueWithBindings: dynamicBindings]} [] in BlockContext>>newProcess {[self value. Processor terminateActive]} On Thu, May 14, 2015 at 6:03 AM, St?phane Rollandin wrote: > Le 13/05/2015 17:31, Chris Muller a ?crit : >> >> Hi St?phane, I checked the server earlier and everything seems to be >> running fine. Now I just did a test upload from the web page and it >> worked fine. >> >> How large is the file that you're trying to upload? > > > 3 Mb; my connexion is very slow though. > > Stef > > > From ma.chris.m at gmail.com Thu May 14 15:38:48 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Thu May 14 15:38:51 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: <55548114.1030201@zogotounga.net> References: <55510971.3070002@zogotounga.net> <5552FBA7.6060307@zogotounga.net> <55548114.1030201@zogotounga.net> Message-ID: Now I just tried a test upload of SqueakV3.sources, a 14M file and the browser reported this error: 413 Request Entity Too Large ________________________________ nginx Next, I tried a smaller one, 3.8MB, and got the same error. So, I'm wondering the same is happening to you but your browser responds differently to that error than chrome? On Thu, May 14, 2015 at 6:03 AM, St?phane Rollandin wrote: > Le 13/05/2015 17:31, Chris Muller a ?crit : >> >> Hi St?phane, I checked the server earlier and everything seems to be >> running fine. Now I just did a test upload from the web page and it >> worked fine. >> >> How large is the file that you're trying to upload? > > > 3 Mb; my connexion is very slow though. > > Stef > > > From asqueaker at gmail.com Thu May 14 15:53:47 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu May 14 15:53:50 2015 Subject: [squeak-dev] release progress In-Reply-To: <159E8A26-7CA4-4914-AA88-3C6258D22811@freudenbergs.de> References: <159E8A26-7CA4-4914-AA88-3C6258D22811@freudenbergs.de> Message-ID: I liked your "Skip" and "Load" even better, but I wasn't asking about the button labels, I'm trying to ask how to properly build a Spur image.. On Thu, May 14, 2015 at 6:24 AM, Bert Freudenberg wrote: > On 13.05.2015, at 20:25, karl ramberg wrote: > > > How about: > > Keep local > Install remote > > > Hmm I like that. > > - Bert - > > > > > > From Lou at Keystone-Software.com Thu May 14 15:54:53 2015 From: Lou at Keystone-Software.com (Louis LaBrunda) Date: Thu May 14 15:55:08 2015 Subject: [squeak-dev] A little puzzle References: <5554C059.3060002@zogotounga.net> Message-ID: Hi St?phane, I don't have time to work this out right now but how about taking a look at #findFirst: and seeing if you can replace your #do: with something like what #findFirst: does. Lou >Hello all, > >I'm finding myself unable to implement something seemingly simple. Here >is the puzzle: > >I want an iterator factory which, given a specific collection, produces >a block taking two arguments, also blocks. One (the doBlock) tells what >should be done for each element of the collection, and the other (the >whileBlock) is a test allowing to abort the whole operation. > >So, something like this: > >Puzzle>>blockIterating: aCollection > > ^ [:doBlock :whileBlock | > aCollection do: [:i | > (whileBlock value: i) ifFalse: [^ self]. > doBlock value: i]]. > > >Then I could do things like the following: > > >| block | > >block := Puzzle new blockIterating: (1 to: 5). > >block value: [:p | Transcript show: p; cr] value: [:p | p < 3] > > > >But the above fails with a 'Block cannot return' (that's the [^ self] >block in the #blockIterating: method). I have attached the code; just do >"Puzzle new fail". > >I can't find a workaround. > >How should I proceed to get a working iterator block ? > >Stef ----------------------------------------------------------- Louis LaBrunda Keystone Software Corp. SkypeMe callto://PhotonDemon mailto:Lou@Keystone-Software.com http://www.Keystone-Software.com From kosi.balazs at ezomer.hu Thu May 14 16:07:00 2015 From: kosi.balazs at ezomer.hu (=?UTF-8?B?QmFsw6F6cyBLw7NzaQ==?=) Date: Thu May 14 16:07:03 2015 Subject: [squeak-dev] A little puzzle In-Reply-To: <5554C059.3060002@zogotounga.net> References: <5554C059.3060002@zogotounga.net> Message-ID: Hi! If your collection understands #readStream, you may write: Puzzle >> blockIterating: aCollection ^[ :doBlock :whileBlock | | stream item | stream := aCollection readStream. [ stream atEnd not and: [ whileBlock value: (item := stream next) ] ] whileTrue: [ doBlock value: item ] ] If it only understands #do:, you may wrap it in a Generator: Puzzle >> blockIterating: aCollection ^[ :doBlock :whileBlock | | stream item | stream := Generator on: [ :g | aCollection do: [ :each | g nextPut: each ] ]. [ stream atEnd not and: [ whileBlock value: (item := stream next) ] ] whileTrue: [ doBlock value: item ] ] If it's not a requirement to return a Block, you may create a class, whose instances respond to #value:value: and sidestep the problem. Cheers, Bal?zs -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/2398f3ea/attachment.htm From jgr.asselin at me.com Thu May 14 16:12:07 2015 From: jgr.asselin at me.com (Raymond Asselin) Date: Thu May 14 16:12:16 2015 Subject: [squeak-dev] Cog VM problem? In-Reply-To: References: Message-ID: <5AB9419C-E156-4532-ACE1-7982741A0630@me.com> When I open image with an earlier VM everything is fine. Changing de method #width doesn't do anything. And I must select each small panel and do: 'start drawing again'. So for now I will stuck to the previous VM. Thank Karl for the suggestion. > Le 2015-05-14 ? 11:26, karl ramberg a ?crit : > > You can test this workaround: > > SimpleBorder>>width > ^width ifNil:[0] > > Open image with an earlier VM and modify that method so it does not return a nil. > > Karl > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/acfb02dd/attachment.htm From lecteur at zogotounga.net Thu May 14 16:38:58 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Thu May 14 16:39:02 2015 Subject: [squeak-dev] A little puzzle In-Reply-To: References: <5554C059.3060002@zogotounga.net> Message-ID: <5554CFA2.2060504@zogotounga.net> Thanks for your answers. Unfortunately in my actual use case (of which the puzzle is just the simplest representation) I am not allowed to work on the collection side (and other iterating methods than #do: can be used by the iterator factory). But actually, I think I just found a workaround: throw an exception, such as Abort which by the way seems to be unused. blockIterating: aCollection ^ [:doBlock :whileBlock | [aCollection do: [:i | (whileBlock value: i) ifFalse: [Abort signal]. doBlock value: i]] on: Abort do: []] Stef From commits at source.squeak.org Thu May 14 16:40:42 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 14 16:40:45 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.981.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.981.mcz ==================== Summary ==================== Name: Morphic-mt.981 Author: mt Time: 14 May 2015, 6:40:07.558 pm UUID: f583e77f-1371-e147-912d-9fdcc47afb7b Ancestors: Morphic-kfr.980 Bugfix in identing list items (tree widgets), which did not update their container's layout correctly when notifying about changed contents (i.e., children). =============== Diff against Morphic-kfr.980 =============== Item was changed: ----- Method: IndentingListItemMorph>>update: (in category 'updating') ----- update: aspect "See ListItemWrapper and subclasses for possible change aspects." aspect = #contents ifTrue: [ + self isExpanded ifTrue: [self toggleExpandedState]. + self canExpand ifTrue: [self toggleExpandedState]. + container adjustSubmorphPositions]. - self isExpanded ifTrue: [ - self toggleExpandedState]. - self canExpand ifTrue: [self toggleExpandedState]]. super update: aspect.! From commits at source.squeak.org Thu May 14 16:45:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 14 16:46:00 2015 Subject: [squeak-dev] The Inbox: HelpSystem-Core-mt.78.mcz Message-ID: Marcel Taeumel uploaded a new version of HelpSystem-Core to project The Inbox: http://source.squeak.org/inbox/HelpSystem-Core-mt.78.mcz ==================== Summary ==================== Name: HelpSystem-Core-mt.78 Author: mt Time: 14 May 2015, 6:45:57.427 pm UUID: d3d02275-f61e-8f4f-91e0-5dcf9b37c8d5 Ancestors: HelpSystem-Core-kfr.77 Class-based help topics are editable again. Help browser updates correctly after edits. =============== Diff against HelpSystem-Core-kfr.77 =============== Item was added: + ----- Method: AbstractHelpTopic>>isEditable (in category 'testing') ----- + isEditable + + ^ false! Item was added: + ----- Method: AbstractHelpTopic>>refresh (in category 'updating') ----- + refresh + "Do nothing."! Item was added: + ----- Method: ClassBasedHelpTopic>>isEditable (in category 'testing') ----- + isEditable + ^ true! Item was added: + ----- Method: ClassBasedHelpTopic>>refresh (in category 'updating') ----- + refresh + + self updateSubtopics. + self changed: #subtopicsUpdated.! Item was changed: ----- Method: ClassBasedHelpTopic>>updateSubtopics (in category 'updating') ----- updateSubtopics | pages | pages := (self helpClass pages collect: [:pageSelectorOrClassName | (Smalltalk hasClassNamed: pageSelectorOrClassName asString) ifTrue: [Smalltalk classNamed: pageSelectorOrClassName asString] ifFalse: [pageSelectorOrClassName]]) asOrderedCollection. self helpClass subclasses select: [:cls | cls ignore not] thenDo: [:cls | pages addIfNotPresent: cls]. ^ subtopics := pages withIndexCollect: [:pageSelectorOrClass :priority | pageSelectorOrClass isBehavior + ifFalse: [(self helpClass perform: pageSelectorOrClass) priority: priority - pages size; key: pageSelectorOrClass; yourself] - ifFalse: [(self helpClass perform: pageSelectorOrClass) priority: priority - pages size; yourself] ifTrue: [pageSelectorOrClass asHelpTopic]]! Item was changed: Model subclass: #HelpBrowser + instanceVariableNames: 'rootTopic currentTopic currentParentTopic result searchTopic topicPath toplevelTopics oldTopic' - instanceVariableNames: 'rootTopic currentTopic result searchTopic topicPath toplevelTopics oldTopic' classVariableNames: 'DefaultHelpBrowser' poolDictionaries: '' category: 'HelpSystem-Core-UI'! !HelpBrowser commentStamp: 'tbn 3/8/2010 09:33' prior: 0! A HelpBrowser is used to display a hierarchy of help topics and their contents. Instance Variables rootTopic: window: treeMorph: contentMorph: rootTopic - xxxxx window - xxxxx treeMorph - xxxxx contentMorph - xxxxx ! Item was changed: ----- Method: HelpBrowser>>accept: (in category 'actions') ----- accept: text "Accept edited text. Compile it into a HelpTopic" + | code parent topicClass topicMethod | + (self currentParentTopic isNil or: [self currentParentTopic isEditable not]) + ifTrue: [^ self inform: 'This help topic cannot be edited.']. + + parent := self currentParentTopic. + topicClass := parent helpClass. + topicMethod := self currentTopic key. + - | code topicClass topicMethod updatedTopic | - (self find: (self currentTopic contents copyFrom: 1 to: 20)) asArray - ifNotEmpty: [:refs | - topicClass := refs first actualClass theNonMetaClass. - topicMethod := refs first selector]. - topicClass = nil ifTrue:[^self inform: 'This help topic can not be edited here']. code := String streamContents:[:s| s nextPutAll: topicMethod. s crtab; nextPutAll: '"This method was automatically generated. Edit it using:"'. s crtab; nextPutAll: '"', self name,' edit: ', topicMethod storeString,'"'. s crtab; nextPutAll: '^HelpTopic'. s crtab: 2; nextPutAll: 'title: ', currentTopic title storeString. s crtab: 2; nextPutAll: 'contents: '. s cr; nextPutAll: (String streamContents:[:c| c nextChunkPutWithStyle: text]) storeString. s nextPutAll:' readStream nextChunkText'. ]. topicClass class compile: code classified: ((topicClass class organization categoryOfElement: topicMethod) ifNil:['pages']). + + parent refresh. + self currentTopic: (parent subtopics detect: [:t | t key = topicMethod]).! - updatedTopic := topicClass perform: topicMethod. - oldTopic := currentTopic. - "self inTopic: self rootTopic replaceCurrentTopicWith: updatedTopic". - self toplevelTopics do:[ :each | self inTopic: each replaceCurrentTopicWith: updatedTopic]. - self changed: #toplevelTopics.. - self changed: #currentTopic. - self changed: #topicContents. - ! Item was changed: ----- Method: HelpBrowser>>buildWith: (in category 'toolbuilder') ----- buildWith: builder | windowSpec treeSpec textSpec searchSpec | windowSpec := builder pluggableWindowSpec new. windowSpec model: self; children: OrderedCollection new; label: #label. searchSpec := builder pluggableInputFieldSpec new. searchSpec model: self; getText: #searchTerm; setText: #searchTerm:; help: 'Search...'; frame: (LayoutFrame fractions: (0@0 corner: 1@0) offsets: (0@0 corner: 0@ (Preferences standardDefaultTextFont height * 2))). windowSpec children add: searchSpec. treeSpec := builder pluggableTreeSpec new. treeSpec model: self; nodeClass: HelpTopicListItemWrapper; roots: #toplevelTopics; getSelected: #currentTopic; setSelected: #currentTopic:; getSelectedPath: #currentTopicPath; + setSelectedParent: #currentParentTopic:; autoDeselect: false; frame: (LayoutFrame fractions: (0@0 corner: 0.3@1) offsets: (0@ (Preferences standardDefaultTextFont height * 2) corner: 0@0)). windowSpec children add: treeSpec. textSpec := builder pluggableTextSpec new. textSpec model: self; getText: #topicContents; setText: #accept:; menu: #codePaneMenu:shifted:; frame: (LayoutFrame fractions: (0.3@0.0 corner: 1@1) offsets: (0@ (Preferences standardDefaultTextFont height * 2) corner: 0@0)). windowSpec children add: textSpec. ^ builder build: windowSpec! Item was added: + ----- Method: HelpBrowser>>currentParentTopic (in category 'accessing') ----- + currentParentTopic + + ^ currentParentTopic! Item was added: + ----- Method: HelpBrowser>>currentParentTopic: (in category 'accessing') ----- + currentParentTopic: aHelpTopic + + currentParentTopic := aHelpTopic.! Item was added: + ----- Method: HelpTopic>>key (in category 'accessing') ----- + key + + ^ key! Item was added: + ----- Method: HelpTopic>>key: (in category 'accessing') ----- + key: aSymbol + + key := aSymbol.! Item was changed: PluggableListItemWrapper subclass: #HelpTopicListItemWrapper + instanceVariableNames: 'parent' - instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'HelpSystem-Core-UI'! !HelpTopicListItemWrapper commentStamp: 'tbn 3/8/2010 09:30' prior: 0! This class implements a list item wrapper for help topics. Instance Variables ! Item was added: + ----- Method: HelpTopicListItemWrapper class>>with:model:parent: (in category 'as yet unclassified') ----- + with: anObject model: aModel parent: aParent + + ^self new + setItem: anObject model: aModel parent: aParent + ! Item was changed: ----- Method: HelpTopicListItemWrapper>>contents (in category 'accessing') ----- contents ^self item subtopics sorted collect: [ :each | + HelpTopicListItemWrapper with: each model: self model parent: self] - HelpTopicListItemWrapper with: each model: self model] ! Item was added: + ----- Method: HelpTopicListItemWrapper>>parent (in category 'accessing') ----- + parent + + ^ parent! Item was added: + ----- Method: HelpTopicListItemWrapper>>parent: (in category 'accessing') ----- + parent: aWrapper + + parent := aWrapper.! Item was added: + ----- Method: HelpTopicListItemWrapper>>setItem:model:parent: (in category 'initialization') ----- + setItem: anObject model: aModel parent: itemParent + + self parent: itemParent. + self setItem: anObject model: aModel.! Item was added: + ----- Method: HelpTopicListItemWrapper>>update: (in category 'accessing') ----- + update: aspect + + super update: aspect. + + "Map the domain-specific aspect to a framework-specific one." + aspect = #subtopicsUpdated ifTrue: [ + self changed: #contents].! From Marcel.Taeumel at hpi.de Thu May 14 16:30:18 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 14 16:47:06 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: References: <1431522622870-4826168.post@n4.nabble.com> <1431523093810-4826172.post@n4.nabble.com> <1431538668657-4826254.post@n4.nabble.com> <1431594129584-4826317.post@n4.nabble.com> Message-ID: <1431621018346-4826371.post@n4.nabble.com> How's this: http://forum.world.st/The-Inbox-HelpSystem-Core-mt-78-mcz-td4826370.html :) Best, Marcel -- View this message in context: http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826371.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Thu May 14 16:56:54 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 14 16:56:56 2015 Subject: [squeak-dev] Cog VM problem? In-Reply-To: <5AB9419C-E156-4532-ACE1-7982741A0630@me.com> References: <5AB9419C-E156-4532-ACE1-7982741A0630@me.com> Message-ID: Ah, ok I method BorderedMorph>>borderStyle add this to top of method: true ifTrue:[^BorderStyle default]. On Thu, May 14, 2015 at 6:12 PM, Raymond Asselin wrote: > When I open image with an earlier VM everything is fine. Changing de > method #width doesn't do anything. > And I must select each small panel and do: 'start drawing again'. So for > now I will stuck to the previous VM. > Thank Karl for the suggestion. > > > Le 2015-05-14 ? 11:26, karl ramberg a ?crit : > > You can test this workaround: > > SimpleBorder>>width > ^width ifNil:[0] > > Open image with an earlier VM and modify that method so it does not return > a nil. > > Karl > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/c06d9b23/attachment.htm From Marcel.Taeumel at hpi.de Thu May 14 16:40:14 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 14 16:56:59 2015 Subject: [squeak-dev] Re: A little puzzle In-Reply-To: <5554CFA2.2060504@zogotounga.net> References: <5554C059.3060002@zogotounga.net> <5554CFA2.2060504@zogotounga.net> Message-ID: <1431621614534-4826373.post@n4.nabble.com> Here without exceptions: list := 1 to: 10. iterator := [:doBlock :whileBlock | list detect: [:ea | | result | (result := whileBlock value: ea) ifTrue: [doBlock value: ea]. result not] ifNone: []]. Best, Marcel -- View this message in context: http://forum.world.st/A-little-puzzle-tp4826352p4826373.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Thu May 14 16:51:12 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 14 17:07:57 2015 Subject: [squeak-dev] Re: Cog VM problem? In-Reply-To: References: Message-ID: <1431622272643-4826376.post@n4.nabble.com> Still, this is only vaguely related to the given stack trace and Eliot should take a look at the real problem here. :-) Let me reprint the problem: ... ByteSymbol(Object)>>doesNotUnderstand: #width:color: MauiMessageMorph(BorderedMorph)>>borderStyle ... The code in BorderedMorph >> borderStyle includes this part: ... BorderStyle width: borderWidth color: borderColor. ... Which should be a class and not a byte symbol. (The whole method looks quite spooky...) Best, Marcel -- View this message in context: http://forum.world.st/Cog-VM-problem-tp4826350p4826376.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Thu May 14 17:20:07 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 14 17:20:09 2015 Subject: [squeak-dev] Re: The Inbox: HelpSystem-Core-kfr.75.mcz In-Reply-To: <1431621018346-4826371.post@n4.nabble.com> References: <1431522622870-4826168.post@n4.nabble.com> <1431523093810-4826172.post@n4.nabble.com> <1431538668657-4826254.post@n4.nabble.com> <1431594129584-4826317.post@n4.nabble.com> <1431621018346-4826371.post@n4.nabble.com> Message-ID: This looks nice :-) Karl On Thu, May 14, 2015 at 6:30 PM, marcel.taeumel wrote: > How's this: > http://forum.world.st/The-Inbox-HelpSystem-Core-mt-78-mcz-td4826370.html > > :) > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/The-Inbox-HelpSystem-Core-kfr-75-mcz-tp4826158p4826371.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/f0477f85/attachment.htm From leves at elte.hu Thu May 14 18:00:25 2015 From: leves at elte.hu (Levente Uzonyi) Date: Thu May 14 18:00:29 2015 Subject: [squeak-dev] A little puzzle In-Reply-To: <5554C059.3060002@zogotounga.net> References: <5554C059.3060002@zogotounga.net> Message-ID: Returning from a block means returning from the method containing that block. (There's no syntax for block return in Smalltalk, because you'd have to be able to tell which block you want to return from to make that be of any use, but blocks are anonymous methods. If you need a named method, then use one.). You get that error, because you've already returned from the method (the block itself was returned), and it's not possible to return twice from the same context. One easy way to make it work is to send a message from inside the block, because then you'll have a separate context to return from. E.g.: Puzzle >> #blockIterating: aCollection ^[ :doBlock :whileBlock | self iterate: aCollection do: doBlock while: whileBlock ]. Puzzle >> #iterate: aCollection do: doBlock while: whileBlock aCollection do: [ :each | (whileBlock value: each) ifFalse: [ ^self ]. doBlock value: each ] Levente On Thu, 14 May 2015, St?phane Rollandin wrote: > Hello all, > > I'm finding myself unable to implement something seemingly simple. Here is > the puzzle: > > I want an iterator factory which, given a specific collection, produces a > block taking two arguments, also blocks. One (the doBlock) tells what should > be done for each element of the collection, and the other (the whileBlock) is > a test allowing to abort the whole operation. > > So, something like this: > > Puzzle>>blockIterating: aCollection > > ^ [:doBlock :whileBlock | > aCollection do: [:i | > (whileBlock value: i) ifFalse: [^ self]. > doBlock value: i]]. > > > Then I could do things like the following: > > > | block | > > block := Puzzle new blockIterating: (1 to: 5). > > block value: [:p | Transcript show: p; cr] value: [:p | p < 3] > > > > But the above fails with a 'Block cannot return' (that's the [^ self] block > in the #blockIterating: method). I have attached the code; just do "Puzzle > new fail". > > I can't find a workaround. > > How should I proceed to get a working iterator block ? > > Stef > From cunningham.cb at gmail.com Thu May 14 18:46:26 2015 From: cunningham.cb at gmail.com (Chris Cunningham) Date: Thu May 14 18:46:29 2015 Subject: [squeak-dev] release progress In-Reply-To: References: <159E8A26-7CA4-4914-AA88-3C6258D22811@freudenbergs.de> Message-ID: or "Apply Changes" and "Ignore Changes" (or skip). And someday (probably not part of this release) add symbols somewhere like + and - to indicate what is being added, and what is being removed. I cannot keep the colors straight to decipher what is happening - often requiring me to open up a current view of the method to decide what is being proposed. But maybe that's just me. -cbc On Thu, May 14, 2015 at 8:53 AM, Chris Muller wrote: > I liked your "Skip" and "Load" even better, but I wasn't asking about > the button labels, I'm trying to ask how to properly build a Spur > image.. > > On Thu, May 14, 2015 at 6:24 AM, Bert Freudenberg > wrote: > > On 13.05.2015, at 20:25, karl ramberg wrote: > > > > > > How about: > > > > Keep local > > Install remote > > > > > > Hmm I like that. > > > > - Bert - > > > > > > > > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/039e77e7/attachment.htm From lecteur at zogotounga.net Thu May 14 18:47:27 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Thu May 14 18:47:36 2015 Subject: [squeak-dev] A little puzzle In-Reply-To: References: <5554C059.3060002@zogotounga.net> Message-ID: <5554EDBF.1050707@zogotounga.net> Ah, so that's the bottom line. Thanks a lot ! I'm now trying to wrap my head around these concepts... It looks like I could also get the return block as an outside argument, like this: Puzzle>>blockIterating: aCollection ^ [:returnBlock | [:doBlock :whileBlock | aCollection do: [:i | (whileBlock value: i) ifFalse: returnBlock. doBlock value: i]]]. and then use it as follow: | block | block := (Puzzle new blockIterating: (1 to: 5)) value: [ ^self]. block value: [:p | Transcript show: p; cr] value: [:p | p < 3] A bit hard to read but it seems to work. Does that make sense ? Stef > Returning from a block means returning from the method containing that > block. (There's no syntax for block return in Smalltalk, because you'd > have to be able to tell which block you want to return from to make that > be of any use, but blocks are anonymous methods. If you need a named > method, then use one.). > You get that error, because you've already returned from the method (the > block itself was returned), and it's not possible to return twice from the > same context. > One easy way to make it work is to send a message from inside the block, > because then you'll have a separate context to return from. > E.g.: > > Puzzle >> #blockIterating: aCollection > > ^[ :doBlock :whileBlock | > self iterate: aCollection do: doBlock while: whileBlock ]. > > Puzzle >> #iterate: aCollection do: doBlock while: whileBlock > > aCollection do: [ :each | > (whileBlock value: each) ifFalse: [ ^self ]. > doBlock value: each ] > > Levente > > On Thu, 14 May 2015, St?phane Rollandin wrote: > >> Hello all, >> >> I'm finding myself unable to implement something seemingly simple. Here is >> the puzzle: >> >> I want an iterator factory which, given a specific collection, produces a >> block taking two arguments, also blocks. One (the doBlock) tells what should >> be done for each element of the collection, and the other (the whileBlock) is >> a test allowing to abort the whole operation. >> >> So, something like this: >> >> Puzzle>>blockIterating: aCollection >> >> ^ [:doBlock :whileBlock | >> aCollection do: [:i | >> (whileBlock value: i) ifFalse: [^ self]. >> doBlock value: i]]. >> >> >> Then I could do things like the following: >> >> >> | block | >> >> block := Puzzle new blockIterating: (1 to: 5). >> >> block value: [:p | Transcript show: p; cr] value: [:p | p < 3] >> >> >> >> But the above fails with a 'Block cannot return' (that's the [^ self] block >> in the #blockIterating: method). I have attached the code; just do "Puzzle >> new fail". >> >> I can't find a workaround. >> >> How should I proceed to get a working iterator block ? >> >> Stef >> > > > > From Das.Linux at gmx.de Thu May 14 18:49:52 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 14 18:49:55 2015 Subject: [squeak-dev] release progress In-Reply-To: References: <159E8A26-7CA4-4914-AA88-3C6258D22811@freudenbergs.de> Message-ID: On 14.05.2015, at 20:46, Chris Cunningham wrote: > or "Apply Changes" and "Ignore Changes" (or skip). > > And someday (probably not part of this release) add symbols somewhere like + and - to indicate what is being added, and what is being removed. I cannot keep the colors straight to decipher what is happening - often requiring me to open up a current view of the method to decide what is being proposed. > We had some Students working on the merging stuff in the last years. We'll review the stuff and probably contribute it to trunk. Stay tuned :) Best regards -Tobias > But maybe that's just me. > -cbc > > On Thu, May 14, 2015 at 8:53 AM, Chris Muller wrote: > I liked your "Skip" and "Load" even better, but I wasn't asking about > the button labels, I'm trying to ask how to properly build a Spur > image.. > > On Thu, May 14, 2015 at 6:24 AM, Bert Freudenberg wrote: > > On 13.05.2015, at 20:25, karl ramberg wrote: > > > > > > How about: > > > > Keep local > > Install remote > > > > > > Hmm I like that. > > > > - Bert - > > > > > > > > > > > > From herbertkoenig at gmx.net Thu May 14 18:54:33 2015 From: herbertkoenig at gmx.net (=?windows-1252?Q?Herbert_K=F6nig?=) Date: Thu May 14 18:54:34 2015 Subject: [squeak-dev] release progress In-Reply-To: References: <159E8A26-7CA4-4914-AA88-3C6258D22811@freudenbergs.de> Message-ID: <5554EF69.2070902@gmx.net> Am 14.05.2015 um 20:46 schrieb Chris Cunningham: > > And someday (probably not part of this release) add symbols somewhere > like + and - to indicate what is being added, and what is being > removed. I cannot keep the colors straight to decipher what is > happening - often requiring me to open up a current view of the method > to decide what is being proposed. > > But maybe that's just me. > -cbc > Me too (in best AOL tradition) but that's exactly what I regularly do. Cheers, Herbert From lecteur at zogotounga.net Thu May 14 19:11:26 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Thu May 14 19:11:28 2015 Subject: [squeak-dev] A little puzzle In-Reply-To: <5554EDBF.1050707@zogotounga.net> References: <5554C059.3060002@zogotounga.net> <5554EDBF.1050707@zogotounga.net> Message-ID: <5554F35E.2050309@zogotounga.net> Hmm, now I see that my last idea does not work if I want to reuse the block... | block | block := (Puzzle new blockIterating: (1 to: 5)) value: [ ^self]. block value: [:p | Transcript show: p; cr] value: [:p | p < 3]. block value: [:p | Transcript show: p; cr] value: [:p | p < 4]. This stops after 1 2 while your implementation works fine: the Transcript shows 1 2 1 2 3 indeed. Stef > Ah, so that's the bottom line. Thanks a lot ! I'm now trying to wrap my > head around these concepts... > > It looks like I could also get the return block as an outside argument, > like this: > > > Puzzle>>blockIterating: aCollection > > ^ [:returnBlock | > [:doBlock :whileBlock | > aCollection do: [:i | > (whileBlock value: i) ifFalse: returnBlock. > doBlock value: i]]]. > > > and then use it as follow: > > > | block | > > block := (Puzzle new blockIterating: (1 to: 5)) value: [ ^self]. > > block value: [:p | Transcript show: p; cr] value: [:p | p < 3] > > > A bit hard to read but it seems to work. Does that make sense ? From commits at source.squeak.org Thu May 14 21:55:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 14 21:55:07 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150514215506.23927.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008602.html Name: Collections.spur-ul.634 Ancestors: Collections-ul.634, Collections.spur-ul.633 Collections-ul.634 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Revert the workaround from Collections-ul.633. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008603.html Name: Collections.spur-mt.635 Ancestors: Collections-mt.635, Collections.spur-ul.634 Collections-mt.635 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Some debug code removed from html readwriter.. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008604.html Name: System.spur-ul.737 Ancestors: System-ul.737, System.spur-kfr.736 System-ul.737 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 #groupBy:having -> #groupBy: ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008605.html Name: Morphic-mt.981 Ancestors: Morphic-kfr.980 Bugfix in identing list items (tree widgets), which did not update their container's layout correctly when notifying about changed contents (i.e., children). ============================================= From unoduetre at poczta.onet.pl Thu May 14 22:42:51 2015 From: unoduetre at poczta.onet.pl (Mateusz Grotek) Date: Thu May 14 22:27:35 2015 Subject: [squeak-dev] A little puzzle In-Reply-To: <5554C059.3060002@zogotounga.net> (from lecteur@zogotounga.net on Thu May 14 17:33:45 2015) Message-ID: <1431643371.20712.1@mglap> Dnia 14.05.2015 17:33:45, St?phane Rollandin napisa?(a): > Hello all, > > I'm finding myself unable to implement something seemingly simple. > Here is the puzzle: > > I want an iterator factory which, given a specific collection, > produces a block taking two arguments, also blocks. One (the doBlock) > tells what should be done for each element of the collection, and the > other (the whileBlock) is a test allowing to abort the whole > operation. > > So, something like this: > > Puzzle>>blockIterating: aCollection > > ^ [:doBlock :whileBlock | > aCollection do: [:i | > (whileBlock value: i) ifFalse: [^ self]. > doBlock value: i]]. > > > Then I could do things like the following: > > > | block | > > block := Puzzle new blockIterating: (1 to: 5). > > block value: [:p | Transcript show: p; cr] value: [:p | p < 3] > > > > But the above fails with a 'Block cannot return' (that's the [^ self] > block in the #blockIterating: method). I have attached the code; just > do "Puzzle new fail". > > I can't find a workaround. > > How should I proceed to get a working iterator block ? > > Stef The behaviour is correct. The ^ operator has lexical scope. It returns from the lexically enclosing method. In this case it would return from blockIterating:, but at this point the method has already returned, so you cannot return from it the second time. What you really want is another method. Just use two separate methods: for: aCollection do: aDoBlock unless: aWhileBlock aCollection do: [:i | (whileBlock value: i) ifFalse: [^ self]. doBlock value: i ] blockIterating: aCollection [:doBlock :whileBlock | self for: aCollection do: doBlock while: whileBlock ]. From unoduetre at poczta.onet.pl Thu May 14 22:47:50 2015 From: unoduetre at poczta.onet.pl (Mateusz Grotek) Date: Thu May 14 22:32:34 2015 Subject: [SPAM] Re: [squeak-dev] A little puzzle In-Reply-To: <1431643371.20712.1@mglap> (from unoduetre@poczta.onet.pl on Fri May 15 00:42:51 2015) References: <5554C059.3060002@zogotounga.net> <1431643371.20712.1@mglap> Message-ID: <1431643670.20712.2@mglap> Oh, sorry for the duplicate answer. I'm tired :-( From eliot.miranda at gmail.com Thu May 14 22:52:09 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 14 22:52:13 2015 Subject: [squeak-dev] Suppressing the No Changes confirmer during update Message-ID: Hi All, I guess because of the multiple ancestors in the Spur bootstrap packages whenever I update a Spur image I see lots of annoying "No Changes" confirmers popping up that have to be clicked on to continue. They come from resolveConflicts (records allSatisfy: [:ea | ea isAncestorMerge]) ifTrue: [MCNoChangesException signal. ^ false]. ^ ((MCMergeResolutionRequest new merger: merger) signal: 'Merging ', records first version info name) = true I see a handler for MCMergeResolutionRequest in upgrade ^self depsSatisfying: [:dep | dep isFulfilledByAncestors not] versionDo: [:ver | (self class upgradeIsMerge and: [ver shouldMerge]) ifFalse: [ver load] ifTrue: [[ver merge] on: MCMergeResolutionRequest do: [:request | request merger conflicts isEmpty ifTrue: [request resume: true] ifFalse: [request pass]]]] displayingProgress: 'upgrading packages' am I right to think that's also the place to put a handler for the MCNoChangesException notification? -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/b04effa4/attachment.htm From jgr.asselin at me.com Thu May 14 23:55:38 2015 From: jgr.asselin at me.com (Raymond Asselin) Date: Thu May 14 23:55:48 2015 Subject: [squeak-dev] Cog VM problem? In-Reply-To: References: <5AB9419C-E156-4532-ACE1-7982741A0630@me.com> Message-ID: <662EE09E-AC24-412F-AF8B-ECB20482DE1F@me.com> With this " true ifTrue:[^BorderStyle default]" the problem is gone now. Thank but the source code is'nt too clear in my opinion and for what I understand this code shadow all the rest of the method. I can't say that I understand what Marcel is saying. It is supposed to be a class and it is not but a symbol?.That you can see it is a symbol not a class is magic for me?a symbol is precede by # is'nt it? Be patient I will finish by understand?. > Le 2015-05-14 ? 12:56, karl ramberg a ?crit : > > Ah, ok > I method > BorderedMorph>>borderSemtyle > add this to top of method: > true ifTrue:[^BorderStyle default]. > > On Thu, May 14, 2015 at 6:12 PM, Raymond Asselin > wrote: > When I open image with an earlier VM everything is fine. Changing de method #width doesn't do anything. > And I must select each small panel and do: 'start drawing again'. So for now I will stuck to the previous VM. > Thank Karl for the suggestion. > > >> Le 2015-05-14 ? 11:26, karl ramberg > a ?crit : >> >> You can test this workaround: >> >> SimpleBorder>>width >> ^width ifNil:[0] >> >> Open image with an earlier VM and modify that method so it does not return a nil. >> >> Karl >> > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/a18df3b7/attachment.htm From eliot.miranda at gmail.com Fri May 15 00:07:49 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 15 00:07:51 2015 Subject: [squeak-dev] Cog VM problem? In-Reply-To: References: Message-ID: Hi Raymond, yes, thanks. We have a regression in the code generator due to recent changes to #== compilation. We're working on it. I hope to have a fix soon. Apologies for the inconvenience. For those of you curious why this only affects the V3 VM, not the Spur VM, the reason is that in Spur the Cogit passes up to 2 argument sends in registers but in V3 it passes only up to 1 arg sends in registers. In (borderWidth = style width and: ["Hah! Try understanding this..." borderColor == style style or: ["#raised/#inset etc" #simple == style style and: [borderColor = style color]]]) ifFalse: [style := borderColor isColor ifTrue: [BorderStyle width: borderWidth color: borderColor] ifFalse: [(BorderStyle perform: borderColor) width: borderWidth "argh."]. self setProperty: #borderStyle toValue: style]. #simple erroneously ends up getting spilled to the stack, so that when the send of width:color: to BorderStyle occurs the code generator emits code to access what it thinks is BorderWidth, but ends up accessing #simple instead. As I say we're working on it and should have a fix soon. On Thu, May 14, 2015 at 8:13 AM, Raymond Asselin wrote: > Cog.app-15.19.3336.tgz > gave me a Debugger window > > > > with these artefacts > This is a MauiDomainMorph > > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/6c5149cb/attachment.htm From lewis at mail.msen.com Fri May 15 00:23:26 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri May 15 00:23:31 2015 Subject: [squeak-dev] Re: [Cuis] Copy vs Clone In-Reply-To: <5554A8C8.3070808@jvuletich.org> References: <20150513154100.b10416eff3a5837cc8fdfde8@whidbey.com> <55540749.4070201@jvuletich.org> <20150514032215.GA5596@shell.msen.com> <5554A8C8.3070808@jvuletich.org> Message-ID: <20150515002326.GA8438@shell.msen.com> Forwarding to squeak-dev for consideration after the next release. Object>>clone can be replaced by #shallowCopy. Perhaps it is time to deprecate #clone. Juan is removing it from Cuis, with reference to this summary by Levente: http://lists.gforge.inria.fr/pipermail/pharo-project/2010-January/019801.html Dave On Thu, May 14, 2015 at 10:53:12AM -0300, Juan Vuletich wrote: > On 5/14/2015 12:22 AM, David T. Lewis wrote: > >On Wed, May 13, 2015 at 11:24:09PM -0300, Juan Vuletich wrote: > >>Does anybody know why #clone was added to Squeak? > >> > >I do not know the historical background, but Object>>clone invokes #primitiveClone > >in the VM. This is an efficient shallow copy, in which the object header and data > >fields are copied to a newly allocated object, and the object hash and GC bits > >are updated in the new copy. > > > >I think that this must have been done for efficiency, to provide the fastest > >possible means of shallow copying an object. The methods in the VM and in Object > >are both old enough that they had no author initials, so this was a very early > >optimization in Squeak. > > > >Dave > > Thanks Dave. > > I searched a bit more and found > http://lists.squeakfoundation.org/pipermail/vm-dev/2014-February/014683.html > and the more detailed > http://lists.gforge.inria.fr/pipermail/pharo-project/2010-January/019801.html > (by Levente). > > After these references, I decided to remove #clone from Cuis. Most > senders were replaced by sends to #shallowCopy (it uses the same VM > primitive). But for several, calling #copy works the same, and #copy > sounds more natural to me. I also refactored several implementations of > #copy et al, in SequenceableCollection and AbstractSound hierarchies. > Will commit to github soon. > > Cheers, > Juan Vuletich From eliot.miranda at gmail.com Fri May 15 04:17:38 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Fri May 15 04:17:42 2015 Subject: [squeak-dev] New CogVMs available Message-ID: at http://www.mirandabanda.org/files/Cog/VM/VM.r3343. CogVM source as per VMMaker.oscog-eem.1303/r3343 Cogit: Fix the regression with #== in the StackToRegisterMappingCogit; a spilled constant must still be dropped from the stack. (fixes the width:color: MNU) Since the method zone does not scavenge PICs, the MNU method in an MNU PIC entry cannot be young. If it is, void the cache (load 0 instead of the method). -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150514/68611275/attachment.htm From Das.Linux at gmx.de Fri May 15 05:33:57 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri May 15 05:34:01 2015 Subject: [squeak-dev] New CogVMs available In-Reply-To: References: Message-ID: ...and updated on the CI. Output on : http://build.squeak.org/job/SqueakTrunk/1482 Best regards -Tobias On 15.05.2015, at 06:17, Eliot Miranda wrote: > at http://www.mirandabanda.org/files/Cog/VM/VM.r3343. > > CogVM source as per VMMaker.oscog-eem.1303/r3343 > > Cogit: > Fix the regression with #== in the StackToRegisterMappingCogit; > a spilled constant must still be dropped from the stack. (fixes the width:color: MNU) > > Since the method zone does not scavenge PICs, the MNU method in an MNU PIC entry > cannot be young. If it is, void the cache (load 0 instead of the method). > -- > best, > Eliot > From Marcel.Taeumel at hpi.de Fri May 15 06:17:04 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Fri May 15 06:33:52 2015 Subject: [squeak-dev] Re: New CogVMs available In-Reply-To: References: Message-ID: <1431670624286-4826445.post@n4.nabble.com> Awesome! :) Best, Marcel -- View this message in context: http://forum.world.st/New-CogVMs-available-tp4826432p4826445.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From nicolaihess at web.de Fri May 15 07:49:28 2015 From: nicolaihess at web.de (Nicolai Hess) Date: Fri May 15 07:49:31 2015 Subject: [squeak-dev] Re: [Vm-dev] Re: Long path name support added for win32 In-Reply-To: References: <1418657714480-4796045.post@n4.nabble.com> <1418675871400-4796073.post@n4.nabble.com> <1418720345362-4796107.post@n4.nabble.com> <20141219033158.GA1153@shell.msen.com> Message-ID: 2015-04-17 23:47 GMT+02:00 Nicolai Hess : > > 2015-03-20 0:39 GMT+01:00 Nicolai Hess : > >> >> 2014-12-19 4:31 GMT+01:00 David T. Lewis : >> >>> >>> Hi Marcel, >>> >>> Thanks for doing this. >>> >>> I opened a Mantis issue so that we will not forget to integrate your >>> changes: >>> >>> http://bugs.squeak.org/view.php?id=7825 >>> >>> Currently, the SVN trunk and oscog branches are identical for >>> sqWin32FilePrims.c, >>> so your update can be applied to both. >>> >>> Your update in the file header looks fine to me. It does not affect >>> copyright, >>> you are just adding a comment to document your update, which is great: >>> >>> * UPDATES: >>> * 1) Support for long path names added by using UNC prefix in that >>> case >>> * (Marcel Taeumel, Hasso Plattner Institute, Postdam, Germany) >>> >>> Eliot - I am not able to test this, but I am sure that Marcel has done >>> so. >>> If this looks good to you then I think we should commit the update to >>> both >>> oscog and trunk in SVN. I think we both have write access to the win32 >>> tree >>> in SVN trunk, so I'm happy to make the update if you agree (or I think >>> you can >>> do it also if you prefer, whichever is easier). >>> >>> I'll close out the Mantis issue whenever we get this completed. >>> >>> Thanks, >>> Dave >>> >>> >>> >>> On Tue, Dec 16, 2014 at 12:59:05AM -0800, Marcel Taeumel wrote: >>> > >>> > sqWin32FilePrims.c < >>> http://forum.world.st/file/n4796107/sqWin32FilePrims.c> >>> > >>> > Hi, Eliot! :) >>> > >>> > Here is the second version that uses alloca. I also modified FAIL to >>> > represent a block thinking of Heartbleed. :D I am not that much into C >>> > patterns. You are free change that. >>> > >>> > Another thing is about the copyright information at the beginning of >>> the >>> > file. I added something, but what is the correct format? >>> > >>> > Best, >>> > Marcel >>> > >>> > >>> > >>> > -- >>> > View this message in context: >>> http://forum.world.st/Long-path-name-support-added-for-win32-tp4796045p4796107.html >>> > Sent from the Squeak VM mailing list archive at Nabble.com. >>> >> >> >> I just found this because I tried to add long path support to pharo. >> What about methods for working with directories dir_create/dir_lookup .... >> Don't you need to do the same in sqWin32Directory.c ? >> > > BUMP > > > BUMP Hello? I verified that creating directories does not work. @esteban do you think we can add this support to pharo or are there to many changes/differences in our implementation? nicolai > > > >> >> nicolai >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150515/f843aaa0/attachment.htm From commits at source.squeak.org Fri May 15 15:46:35 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 15:46:38 2015 Subject: [squeak-dev] The Trunk: MonticelloConfigurations-eem.134.mcz Message-ID: Eliot Miranda uploaded a new version of MonticelloConfigurations to project The Trunk: http://source.squeak.org/trunk/MonticelloConfigurations-eem.134.mcz ==================== Summary ==================== Name: MonticelloConfigurations-eem.134 Author: eem Time: 15 May 2015, 8:46:24.696 am UUID: 55bf6d09-e0ad-4ce2-b861-85e35d611dcb Ancestors: MonticelloConfigurations-dtl.133 Suppress the annoying "No CHanges" notifiers during update. =============== Diff against MonticelloConfigurations-dtl.133 =============== Item was changed: ----- Method: MCConfiguration>>upgrade (in category 'actions') ----- upgrade + ^self depsSatisfying: + [:dep | dep isFulfilledByAncestors not] + versionDo: + [:ver | - ^self depsSatisfying: [:dep | dep isFulfilledByAncestors not] - versionDo: [:ver | (self class upgradeIsMerge and: [ver shouldMerge]) ifFalse: [ver load] + ifTrue: + [[ver merge] + on: MCNoChangesException + do: [:req| req resume ] + on: MCMergeResolutionRequest + do: [:request | + request merger conflicts isEmpty + ifTrue: [request resume: true] + ifFalse: [request pass]]]] + displayingProgress: 'upgrading packages'! - ifTrue: [[ver merge] - on: MCMergeResolutionRequest do: [:request | - request merger conflicts isEmpty - ifTrue: [request resume: true] - ifFalse: [request pass]]]] - displayingProgress: 'upgrading packages' - ! From sean at clipperadams.com Fri May 15 15:34:26 2015 From: sean at clipperadams.com (Sean P. DeNigris) Date: Fri May 15 15:51:17 2015 Subject: [squeak-dev] Re: A little puzzle In-Reply-To: <5554CFA2.2060504@zogotounga.net> References: <5554C059.3060002@zogotounga.net> <5554CFA2.2060504@zogotounga.net> Message-ID: <1431704066916-4826529.post@n4.nabble.com> St?phane Rollandin wrote > But actually, I think I just found a workaround: throw an exception, > such as Abort which by the way seems to be unused. I would strongly advise against this. Firstly, exceptions are conceptually a way to indicate a condition that is... exceptional! So in that sense it's confusing. But maybe more importantly, I've encountered several areas in Pharo where exceptions were hijacked in this way and it led to lots of pain. The one that comes to mind first is the mechanism to show progress during a long operation. Because exceptions were used inappropriately, only one interested party would be notified, and then they would swallow the exception. The appropriate technique in that case was an observer pattern, now implemented with announcements. I encourage you to find a corresponding pattern! ----- Cheers, Sean -- View this message in context: http://forum.world.st/A-little-puzzle-tp4826352p4826529.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Fri May 15 17:10:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 17:10:26 2015 Subject: [squeak-dev] The Trunk: System.spur-mt.724.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-mt.724.mcz ==================== Summary ==================== Name: System.spur-mt.724 Author: eem Time: 12 May 2015, 3:36:53.407 pm UUID: 6dfaa338-95df-4cd9-89d2-d1d781aa73c3 Ancestors: System-mt.724, System.spur-ul.723 System-mt.724 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Move check for big displays from SystemWindow to RealEstateManager. Some refactorings in RealEstateManager. =============== Diff against System-mt.724 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From leves at elte.hu Fri May 15 18:56:38 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri May 15 18:56:40 2015 Subject: [squeak-dev] Can't upload to SqueakMap In-Reply-To: <55548114.1030201@zogotounga.net> References: <55510971.3070002@zogotounga.net> <5552FBA7.6060307@zogotounga.net> <55548114.1030201@zogotounga.net> Message-ID: The upload limit was less than 3 MB. It should work now, so please try again. Levente On Thu, 14 May 2015, St?phane Rollandin wrote: > Le 13/05/2015 17:31, Chris Muller a ?crit : >> Hi St?phane, I checked the server earlier and everything seems to be >> running fine. Now I just did a test upload from the web page and it >> worked fine. >> >> How large is the file that you're trying to upload? > > 3 Mb; my connexion is very slow though. > > Stef > > > > > From commits at source.squeak.org Fri May 15 21:55:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 21:55:06 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150515215505.1987.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008606.html Name: MonticelloConfigurations-eem.134 Ancestors: MonticelloConfigurations-dtl.133 Suppress the annoying "No CHanges" notifiers during update. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008607.html Name: System.spur-mt.724 Ancestors: System-mt.724, System.spur-ul.723 System-mt.724 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Move check for big displays from SystemWindow to RealEstateManager. Some refactorings in RealEstateManager. ============================================= From commits at source.squeak.org Sat May 16 00:00:37 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 22:00:42 2015 Subject: [squeak-dev] The Trunk: 46Deprecated-mt.3.mcz Message-ID: Chris Muller uploaded a new version of 46Deprecated to project The Trunk: http://source.squeak.org/trunk/46Deprecated-mt.3.mcz ==================== Summary ==================== Name: 46Deprecated-mt.3 Author: mt Time: 8 May 2015, 12:35:45.873 pm UUID: 8ff69d8d-675d-2342-a98a-342fb0a5ddbd Ancestors: 46Deprecated-mt.2 Old search bar morph added to keep that code in case of regression bugs with the new, toolbuilder-driven search bar. ==================== Snapshot ==================== SystemOrganization addCategory: #'46Deprecated-Morphic'! PluggableListMorph subclass: #PluggableMessageCategoryListMorph instanceVariableNames: 'getRawListSelector priorRawList' classVariableNames: '' poolDictionaries: '' category: '46Deprecated-Morphic'! !PluggableMessageCategoryListMorph commentStamp: '' prior: 0! A variant of PluggableListMorph designed specially for efficient handling of the --all-- feature in message-list panes. In order to be able *quickly* to check whether there has been an external change to the list, we cache the raw list for identity comparison (the actual list is a combination of the --all-- element and the the actual list).! ----- Method: PluggableMessageCategoryListMorph class>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel ^ self new on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel! ----- Method: PluggableMessageCategoryListMorph>>getList (in category 'model access') ----- getList "Differs from the generic in that here we obtain and cache the raw list, then cons it together with the special '-- all --' item to produce the list to be used in the browser. This special handling is done in order to avoid excessive and unnecessary reformulation of the list in the step method" getRawListSelector == nil ifTrue: ["should not happen!!" priorRawList := nil. ^ #()]. model classListIndex = 0 ifTrue: [^ priorRawList := list := Array new]. priorRawList := model perform: getRawListSelector. list := (Array with: ClassOrganizer allCategory), priorRawList. ^list! ----- Method: PluggableMessageCategoryListMorph>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel self model: anObject. getListSelector := getListSel. getIndexSelector := getSelectionSel. setIndexSelector := setSelectionSel. getMenuSelector := getMenuSel. keystrokeActionSelector := keyActionSel. autoDeselect := true. self borderWidth: 1. getRawListSelector := getRawSel. self updateList. self selectionIndex: self getCurrentSelectionIndex. self initForKeystrokes! ----- Method: PluggableMessageCategoryListMorph>>verifyContents (in category 'updating') ----- verifyContents | newList existingSelection anIndex newRawList | (model editSelection == #editComment) ifTrue: [^ self]. model classListIndex = 0 ifTrue: [^ self]. newRawList := model perform: getRawListSelector. newRawList == priorRawList ifTrue: [^ self]. "The usual case; very fast" priorRawList := newRawList. newList := (Array with: ClassOrganizer allCategory), priorRawList. list = newList ifTrue: [^ self]. existingSelection := self selection. self updateList. (anIndex := newList indexOf: existingSelection ifAbsent: [nil]) ifNotNil: [model noteSelectionIndex: anIndex for: getListSelector. self selectionIndex: anIndex] ifNil: [self changeModelSelection: 0]! ----- Method: MorphicProject>>exportSegmentWithCatagories:classes:fileName:directory: (in category '*46Deprecated') ----- exportSegmentWithCatagories: catList classes: classList fileName: aFileName directory: aDirectory "Store my project out on the disk as an *exported* ImageSegment. All outPointers will be in a form that can be resolved in the target image. Name it .extSeg. What do we do about subProjects, especially if they are out as local image segments? Force them to come in? Player classes are included automatically." | is str ans revertSeg roots holder | self flag: #toRemove. self halt. "unused" "world == World ifTrue: [^ false]." "self inform: 'Can''t send the current world out'." world ifNil: [^ false]. world presenter ifNil: [^ false]. ScrapBook default emptyScrapBook. world currentHand pasteBuffer: nil. "don't write the paste buffer." world currentHand mouseOverHandler initialize. "forget about any references here" "Display checkCurrentHandForObjectToPaste." Command initialize. world clearCommandHistory. world fullReleaseCachedState; releaseViewers. world cleanseStepList. world localFlapTabs size = world flapTabs size ifFalse: [ self error: 'Still holding onto Global flaps']. world releaseSqueakPages. holder := Project allProjects. "force them in to outPointers, where DiskProxys are made" "Just export me, not my previous version" revertSeg := self parameterAt: #revertToMe. self projectParameters removeKey: #revertToMe ifAbsent: []. roots := OrderedCollection new. roots add: self; add: world; add: transcript; add: changeSet; add: thumbnail. roots add: world activeHand; addAll: classList; addAll: (classList collect: [:cls | cls class]). roots := roots reject: [ :x | x isNil]. "early saves may not have active hand or thumbnail" catList do: [:sysCat | (SystemOrganization listAtCategoryNamed: sysCat asSymbol) do: [:symb | roots add: (Smalltalk at: symb); add: (Smalltalk at: symb) class]]. is := ImageSegment new copySmartRootsExport: roots asArray. "old way was (is := ImageSegment new copyFromRootsForExport: roots asArray)" is state = #tooBig ifTrue: [^ false]. str := ''. "considered legal to save a project that has never been entered" (is outPointers includes: world) ifTrue: [ str := str, '\Project''s own world is not in the segment.' withCRs]. str isEmpty ifFalse: [ ans := (UIManager default chooseFrom: #('Do not write file' 'Write file anyway' 'Debug') title: str). ans = 1 ifTrue: [ revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. ^ false]. ans = 3 ifTrue: [self halt: 'Segment not written']]. is writeForExportWithSources: aFileName inDirectory: aDirectory. revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. holder. world flapTabs do: [:ft | (ft respondsTo: #unhibernate) ifTrue: [ft unhibernate]]. is arrayOfRoots do: [:obj | obj isScriptEditorMorph ifTrue: [obj unhibernate]]. ^ true ! ----- Method: HierarchyBrowser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser" ^ self classList collect: [:aName | aName copyWithout: $ ]! ----- Method: ScrollPane>>alwaysShowHScrollBar: (in category '*46Deprecated') ----- alwaysShowHScrollBar: bool self flag: #deprecated. self setProperty: #hScrollBarAlways toValue: bool. bool ifTrue: [self hScrollBarPolicy: #always] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>alwaysShowScrollBars: (in category '*46Deprecated') ----- alwaysShowScrollBars: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self alwaysShowHScrollBar: bool; alwaysShowVScrollBar: bool. ! ----- Method: ScrollPane>>alwaysShowVScrollBar: (in category '*46Deprecated') ----- alwaysShowVScrollBar: bool self flag: #deprecated. self setProperty: #vScrollBarAlways toValue: bool. bool ifTrue: [self vScrollBarPolicy: #always] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>hInitScrollBarTEMPORARY (in category '*46Deprecated') ----- hInitScrollBarTEMPORARY "This is called lazily before the hScrollBar is accessed in a couple of places. It is provided to transition old ScrollPanes lying around that do not have an hScrollBar. Once it has been in the image for awhile, and all ScrollPanes have an hScrollBar, this method and it's references can be removed. " "Temporary method for filein of changeset" hScrollBar ifNil: [hScrollBar := ScrollBar new model: self slotName: 'hScrollBar'. hScrollBar borderWidth: 1; borderColor: Color black. self resizeScrollBars; setScrollDeltas; hideOrShowScrollBars]. ! ----- Method: ScrollPane>>hideHScrollBarIndefinitely: (in category '*46Deprecated') ----- hideHScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool. bool ifTrue: [self hScrollBarPolicy: #never] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>hideScrollBarsIndefinitely: (in category '*46Deprecated') ----- hideScrollBarsIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self hideVScrollBarIndefinitely: bool. self hideHScrollBarIndefinitely: bool. ! ----- Method: ScrollPane>>hideVScrollBarIndefinitely: (in category '*46Deprecated') ----- hideVScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool. bool ifTrue: [self vScrollBarPolicy: #never] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>isAScrollbarShowing (in category '*46Deprecated') ----- isAScrollbarShowing "Return true if a either retractable scroll bar is currently showing" self flag: #deprectaed. "mt: Use #isAnyScrollbarShowing" retractableScrollBar ifFalse:[^true]. ^self hIsScrollbarShowing or: [self vIsScrollbarShowing] ! ----- Method: ScrollPane>>showHScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showHScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool not. self setProperty: #hScrollBarAlways toValue: bool not. bool ifTrue: [self hScrollBarPolicy: #whenNeeded] ifFalse: [self hScrollBarPolicy: #never]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>showScrollBarsOnlyWhenNeeded: (in category '*46Deprecated') ----- showScrollBarsOnlyWhenNeeded: bool self flag: #deprecated. self showHScrollBarOnlyWhenNeeded: bool. self showVScrollBarOnlyWhenNeeded: bool. ! ----- Method: ScrollPane>>showVScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showVScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool not. self setProperty: #vScrollBarAlways toValue: bool not. bool ifTrue: [self vScrollBarPolicy: #whenNeeded] ifFalse: [self vScrollBarPolicy: #never]. self vHideOrShowScrollBar. ! TextMorph subclass: #SearchBarMorph instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: '46Deprecated-Morphic'! ----- Method: SearchBarMorph>>activate: (in category 'search') ----- activate: event event hand newKeyboardFocus: self. self selectAll! ----- Method: SearchBarMorph>>fillStyle (in category 'initialize') ----- fillStyle ^backgroundColor! ----- Method: SearchBarMorph>>initialize (in category 'initialize') ----- initialize super initialize. text := Text new. backgroundColor := TranslucentColor gray alpha: 0.3. self width: 200. self crAction: (MessageSend receiver: self selector: #smartSearch:). self setBalloonText: 'Searches for globals and methods'.! ----- Method: SearchBarMorph>>smartSearch: (in category 'search') ----- smartSearch: evt "Take the user input and perform an appropriate search" | input newContents | input := self contents asString ifEmpty:[^self]. (Smalltalk bindingOf: input) ifNotNil:[:assoc| | global | "It's a global or a class" global := assoc value. ^ToolSet browse: (global isBehavior ifTrue:[global] ifFalse:[global class]) selector: nil. ]. (SystemNavigation new allImplementorsOf: input asSymbol) ifNotEmpty:[:list| ^SystemNavigation new browseMessageList: list name: 'Implementors of ' , input ]. input first isUppercase ifTrue:[ (UIManager default classFromPattern: input withCaption: '') ifNotNil:[:aClass| ^ToolSet browse: aClass selector: nil. ]. ] ifFalse:[ ^ToolSet default browseMessageNames: input ]. newContents := input, ' -- not found.'. self newContents: newContents; selectFrom: input size+1 to: newContents size. evt hand newKeyboardFocus: self! ----- Method: CodeHolder>>abbreviatedWordingFor: (in category '*46Deprecated') ----- abbreviatedWordingFor: aButtonSelector "Answer the abbreviated form of wording, from a static table. Answer nil if there is no entry -- in which case the long form will be used on the corresponding browser button." #( (browseMethodFull 'browse') (browseSendersOfMessages 'senders') (browseMessages 'impl') (browseVersions 'vers') (methodHierarchy 'inher') (classHierarchy 'hier') (browseVariableReferences 'refs') (offerMenu 'menu')) do: [:pair | pair first == aButtonSelector ifTrue: [^ pair second]]. ^ nil! ----- Method: CodeHolder>>showingDiffsString (in category '*46Deprecated') ----- showingDiffsString "Answer a string representing whether I'm showing diffs. Not sent any more but retained so that prexisting buttons that sent this will not raise errors." ^ (self showingRegularDiffs ifTrue: [''] ifFalse: ['']), 'showDiffs'! ----- Method: CodeHolder>>toggleDiff (in category '*46Deprecated') ----- toggleDiff "Retained for backward compatibility with existing buttons in existing images" self toggleDiffing! ----- Method: Browser>>classComment:notifying: (in category '*46Deprecated') ----- classComment: aText notifying: aPluggableTextMorph "The user has just entered aText. It may be all red (a side-effect of replacing the default comment), so remove the color if it is." | theClass cleanedText redRange | theClass := self selectedClassOrMetaClass. theClass ifNotNil: [cleanedText := aText asText. redRange := cleanedText rangeOf: TextColor red startingAt: 1. redRange size = cleanedText size ifTrue: [cleanedText removeAttribute: TextColor red from: 1 to: redRange last ]. theClass comment: aText stamp: Utilities changeStamp]. self changed: #classCommentText. ^ true! ----- Method: Browser>>defineMessage:notifying: (in category '*46Deprecated') ----- defineMessage: aString notifying: aController self deprecated: 'Use Browser >> #defineMessageFrom:notifying:. This returns a Symbol or nil, not a Boolean.'. ^ (self defineMessageFrom: aString notifying: aController) notNil.! ----- Method: Browser>>messageListSingleton (in category '*46Deprecated') ----- messageListSingleton | name | name := self selectedMessageName. ^ name ifNil: [Array new] ifNotNil: [Array with: name]! ----- Method: Browser>>optionalAnnotationHeight (in category '*46Deprecated') ----- optionalAnnotationHeight ^ 10! ----- Method: Browser>>optionalButtonHeight (in category '*46Deprecated') ----- optionalButtonHeight ^ 10! ----- Method: Browser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser. This hook is provided so that HierarchyBrowsers can indicate their restricted subset. For generic Browsers, the entire list of classes known to Smalltalk is provided, though of course that really only is accurate in the case of full system browsers." ^ Smalltalk classNames! From commits at source.squeak.org Sat May 16 00:00:53 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 22:00:59 2015 Subject: [squeak-dev] The Trunk: 46Deprecated-mt.2.mcz Message-ID: Chris Muller uploaded a new version of 46Deprecated to project The Trunk: http://source.squeak.org/trunk/46Deprecated-mt.2.mcz ==================== Summary ==================== Name: 46Deprecated-mt.2 Author: mt Time: 3 May 2015, 2:43:14.241 pm UUID: a45140cf-2faa-8642-a1b8-2f81eaea8990 Ancestors: 46Deprecated-mt.1 Added a widget that was once used for showing message category lists. ==================== Snapshot ==================== SystemOrganization addCategory: #'46Deprecated-Morphic-Pluggable Widgets'! ----- Method: ScrollPane>>alwaysShowHScrollBar: (in category '*46Deprecated') ----- alwaysShowHScrollBar: bool self flag: #deprecated. self setProperty: #hScrollBarAlways toValue: bool. bool ifTrue: [self hScrollBarPolicy: #always] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>alwaysShowScrollBars: (in category '*46Deprecated') ----- alwaysShowScrollBars: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self alwaysShowHScrollBar: bool; alwaysShowVScrollBar: bool. ! ----- Method: ScrollPane>>alwaysShowVScrollBar: (in category '*46Deprecated') ----- alwaysShowVScrollBar: bool self flag: #deprecated. self setProperty: #vScrollBarAlways toValue: bool. bool ifTrue: [self vScrollBarPolicy: #always] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>hInitScrollBarTEMPORARY (in category '*46Deprecated') ----- hInitScrollBarTEMPORARY "This is called lazily before the hScrollBar is accessed in a couple of places. It is provided to transition old ScrollPanes lying around that do not have an hScrollBar. Once it has been in the image for awhile, and all ScrollPanes have an hScrollBar, this method and it's references can be removed. " "Temporary method for filein of changeset" hScrollBar ifNil: [hScrollBar := ScrollBar new model: self slotName: 'hScrollBar'. hScrollBar borderWidth: 1; borderColor: Color black. self resizeScrollBars; setScrollDeltas; hideOrShowScrollBars]. ! ----- Method: ScrollPane>>hideHScrollBarIndefinitely: (in category '*46Deprecated') ----- hideHScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool. bool ifTrue: [self hScrollBarPolicy: #never] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>hideScrollBarsIndefinitely: (in category '*46Deprecated') ----- hideScrollBarsIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self hideVScrollBarIndefinitely: bool. self hideHScrollBarIndefinitely: bool. ! ----- Method: ScrollPane>>hideVScrollBarIndefinitely: (in category '*46Deprecated') ----- hideVScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool. bool ifTrue: [self vScrollBarPolicy: #never] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>isAScrollbarShowing (in category '*46Deprecated') ----- isAScrollbarShowing "Return true if a either retractable scroll bar is currently showing" self flag: #deprectaed. "mt: Use #isAnyScrollbarShowing" retractableScrollBar ifFalse:[^true]. ^self hIsScrollbarShowing or: [self vIsScrollbarShowing] ! ----- Method: ScrollPane>>showHScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showHScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool not. self setProperty: #hScrollBarAlways toValue: bool not. bool ifTrue: [self hScrollBarPolicy: #whenNeeded] ifFalse: [self hScrollBarPolicy: #never]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>showScrollBarsOnlyWhenNeeded: (in category '*46Deprecated') ----- showScrollBarsOnlyWhenNeeded: bool self flag: #deprecated. self showHScrollBarOnlyWhenNeeded: bool. self showVScrollBarOnlyWhenNeeded: bool. ! ----- Method: ScrollPane>>showVScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showVScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool not. self setProperty: #vScrollBarAlways toValue: bool not. bool ifTrue: [self vScrollBarPolicy: #whenNeeded] ifFalse: [self vScrollBarPolicy: #never]. self vHideOrShowScrollBar. ! PluggableListMorph subclass: #PluggableMessageCategoryListMorph instanceVariableNames: 'getRawListSelector priorRawList' classVariableNames: '' poolDictionaries: '' category: '46Deprecated-Morphic-Pluggable Widgets'! !PluggableMessageCategoryListMorph commentStamp: '' prior: 0! A variant of PluggableListMorph designed specially for efficient handling of the --all-- feature in message-list panes. In order to be able *quickly* to check whether there has been an external change to the list, we cache the raw list for identity comparison (the actual list is a combination of the --all-- element and the the actual list).! ----- Method: PluggableMessageCategoryListMorph class>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel ^ self new on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel! ----- Method: PluggableMessageCategoryListMorph>>getList (in category 'model access') ----- getList "Differs from the generic in that here we obtain and cache the raw list, then cons it together with the special '-- all --' item to produce the list to be used in the browser. This special handling is done in order to avoid excessive and unnecessary reformulation of the list in the step method" getRawListSelector == nil ifTrue: ["should not happen!!" priorRawList := nil. ^ #()]. model classListIndex = 0 ifTrue: [^ priorRawList := list := Array new]. priorRawList := model perform: getRawListSelector. list := (Array with: ClassOrganizer allCategory), priorRawList. ^list! ----- Method: PluggableMessageCategoryListMorph>>on:list:selected:changeSelected:menu:keystroke:getRawListSelector: (in category 'as yet unclassified') ----- on: anObject list: getListSel selected: getSelectionSel changeSelected: setSelectionSel menu: getMenuSel keystroke: keyActionSel getRawListSelector: getRawSel self model: anObject. getListSelector := getListSel. getIndexSelector := getSelectionSel. setIndexSelector := setSelectionSel. getMenuSelector := getMenuSel. keystrokeActionSelector := keyActionSel. autoDeselect := true. self borderWidth: 1. getRawListSelector := getRawSel. self updateList. self selectionIndex: self getCurrentSelectionIndex. self initForKeystrokes! ----- Method: PluggableMessageCategoryListMorph>>verifyContents (in category 'updating') ----- verifyContents | newList existingSelection anIndex newRawList | (model editSelection == #editComment) ifTrue: [^ self]. model classListIndex = 0 ifTrue: [^ self]. newRawList := model perform: getRawListSelector. newRawList == priorRawList ifTrue: [^ self]. "The usual case; very fast" priorRawList := newRawList. newList := (Array with: ClassOrganizer allCategory), priorRawList. list = newList ifTrue: [^ self]. existingSelection := self selection. self updateList. (anIndex := newList indexOf: existingSelection ifAbsent: [nil]) ifNotNil: [model noteSelectionIndex: anIndex for: getListSelector. self selectionIndex: anIndex] ifNil: [self changeModelSelection: 0]! ----- Method: MorphicProject>>exportSegmentWithCatagories:classes:fileName:directory: (in category '*46Deprecated') ----- exportSegmentWithCatagories: catList classes: classList fileName: aFileName directory: aDirectory "Store my project out on the disk as an *exported* ImageSegment. All outPointers will be in a form that can be resolved in the target image. Name it .extSeg. What do we do about subProjects, especially if they are out as local image segments? Force them to come in? Player classes are included automatically." | is str ans revertSeg roots holder | self flag: #toRemove. self halt. "unused" "world == World ifTrue: [^ false]." "self inform: 'Can''t send the current world out'." world ifNil: [^ false]. world presenter ifNil: [^ false]. ScrapBook default emptyScrapBook. world currentHand pasteBuffer: nil. "don't write the paste buffer." world currentHand mouseOverHandler initialize. "forget about any references here" "Display checkCurrentHandForObjectToPaste." Command initialize. world clearCommandHistory. world fullReleaseCachedState; releaseViewers. world cleanseStepList. world localFlapTabs size = world flapTabs size ifFalse: [ self error: 'Still holding onto Global flaps']. world releaseSqueakPages. holder := Project allProjects. "force them in to outPointers, where DiskProxys are made" "Just export me, not my previous version" revertSeg := self parameterAt: #revertToMe. self projectParameters removeKey: #revertToMe ifAbsent: []. roots := OrderedCollection new. roots add: self; add: world; add: transcript; add: changeSet; add: thumbnail. roots add: world activeHand; addAll: classList; addAll: (classList collect: [:cls | cls class]). roots := roots reject: [ :x | x isNil]. "early saves may not have active hand or thumbnail" catList do: [:sysCat | (SystemOrganization listAtCategoryNamed: sysCat asSymbol) do: [:symb | roots add: (Smalltalk at: symb); add: (Smalltalk at: symb) class]]. is := ImageSegment new copySmartRootsExport: roots asArray. "old way was (is := ImageSegment new copyFromRootsForExport: roots asArray)" is state = #tooBig ifTrue: [^ false]. str := ''. "considered legal to save a project that has never been entered" (is outPointers includes: world) ifTrue: [ str := str, '\Project''s own world is not in the segment.' withCRs]. str isEmpty ifFalse: [ ans := (UIManager default chooseFrom: #('Do not write file' 'Write file anyway' 'Debug') title: str). ans = 1 ifTrue: [ revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. ^ false]. ans = 3 ifTrue: [self halt: 'Segment not written']]. is writeForExportWithSources: aFileName inDirectory: aDirectory. revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. holder. world flapTabs do: [:ft | (ft respondsTo: #unhibernate) ifTrue: [ft unhibernate]]. is arrayOfRoots do: [:obj | obj isScriptEditorMorph ifTrue: [obj unhibernate]]. ^ true ! ----- Method: Browser>>classComment:notifying: (in category '*46Deprecated') ----- classComment: aText notifying: aPluggableTextMorph "The user has just entered aText. It may be all red (a side-effect of replacing the default comment), so remove the color if it is." | theClass cleanedText redRange | theClass := self selectedClassOrMetaClass. theClass ifNotNil: [cleanedText := aText asText. redRange := cleanedText rangeOf: TextColor red startingAt: 1. redRange size = cleanedText size ifTrue: [cleanedText removeAttribute: TextColor red from: 1 to: redRange last ]. theClass comment: aText stamp: Utilities changeStamp]. self changed: #classCommentText. ^ true! ----- Method: Browser>>defineMessage:notifying: (in category '*46Deprecated') ----- defineMessage: aString notifying: aController self deprecated: 'Use Browser >> #defineMessageFrom:notifying:. This returns a Symbol or nil, not a Boolean.'. ^ (self defineMessageFrom: aString notifying: aController) notNil.! ----- Method: Browser>>messageListSingleton (in category '*46Deprecated') ----- messageListSingleton | name | name := self selectedMessageName. ^ name ifNil: [Array new] ifNotNil: [Array with: name]! ----- Method: Browser>>optionalAnnotationHeight (in category '*46Deprecated') ----- optionalAnnotationHeight ^ 10! ----- Method: Browser>>optionalButtonHeight (in category '*46Deprecated') ----- optionalButtonHeight ^ 10! ----- Method: Browser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser. This hook is provided so that HierarchyBrowsers can indicate their restricted subset. For generic Browsers, the entire list of classes known to Smalltalk is provided, though of course that really only is accurate in the case of full system browsers." ^ Smalltalk classNames! ----- Method: CodeHolder>>abbreviatedWordingFor: (in category '*46Deprecated') ----- abbreviatedWordingFor: aButtonSelector "Answer the abbreviated form of wording, from a static table. Answer nil if there is no entry -- in which case the long form will be used on the corresponding browser button." #( (browseMethodFull 'browse') (browseSendersOfMessages 'senders') (browseMessages 'impl') (browseVersions 'vers') (methodHierarchy 'inher') (classHierarchy 'hier') (browseVariableReferences 'refs') (offerMenu 'menu')) do: [:pair | pair first == aButtonSelector ifTrue: [^ pair second]]. ^ nil! ----- Method: CodeHolder>>showingDiffsString (in category '*46Deprecated') ----- showingDiffsString "Answer a string representing whether I'm showing diffs. Not sent any more but retained so that prexisting buttons that sent this will not raise errors." ^ (self showingRegularDiffs ifTrue: [''] ifFalse: ['']), 'showDiffs'! ----- Method: CodeHolder>>toggleDiff (in category '*46Deprecated') ----- toggleDiff "Retained for backward compatibility with existing buttons in existing images" self toggleDiffing! ----- Method: HierarchyBrowser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser" ^ self classList collect: [:aName | aName copyWithout: $ ]! From commits at source.squeak.org Sat May 16 00:01:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 22:01:17 2015 Subject: [squeak-dev] The Trunk: 46Deprecated-mt.1.mcz Message-ID: Chris Muller uploaded a new version of 46Deprecated to project The Trunk: http://source.squeak.org/trunk/46Deprecated-mt.1.mcz ==================== Summary ==================== Name: 46Deprecated-mt.1 Author: mt Time: 1 May 2015, 2:33:12.046 pm UUID: a2c7055c-a7ec-4442-b80a-8e076a79e39c Ancestors: Some deprecations for 4.6 added. ==================== Snapshot ==================== ----- Method: MorphicProject>>exportSegmentWithCatagories:classes:fileName:directory: (in category '*46Deprecated') ----- exportSegmentWithCatagories: catList classes: classList fileName: aFileName directory: aDirectory "Store my project out on the disk as an *exported* ImageSegment. All outPointers will be in a form that can be resolved in the target image. Name it .extSeg. What do we do about subProjects, especially if they are out as local image segments? Force them to come in? Player classes are included automatically." | is str ans revertSeg roots holder | self flag: #toRemove. self halt. "unused" "world == World ifTrue: [^ false]." "self inform: 'Can''t send the current world out'." world ifNil: [^ false]. world presenter ifNil: [^ false]. ScrapBook default emptyScrapBook. world currentHand pasteBuffer: nil. "don't write the paste buffer." world currentHand mouseOverHandler initialize. "forget about any references here" "Display checkCurrentHandForObjectToPaste." Command initialize. world clearCommandHistory. world fullReleaseCachedState; releaseViewers. world cleanseStepList. world localFlapTabs size = world flapTabs size ifFalse: [ self error: 'Still holding onto Global flaps']. world releaseSqueakPages. holder := Project allProjects. "force them in to outPointers, where DiskProxys are made" "Just export me, not my previous version" revertSeg := self parameterAt: #revertToMe. self projectParameters removeKey: #revertToMe ifAbsent: []. roots := OrderedCollection new. roots add: self; add: world; add: transcript; add: changeSet; add: thumbnail. roots add: world activeHand; addAll: classList; addAll: (classList collect: [:cls | cls class]). roots := roots reject: [ :x | x isNil]. "early saves may not have active hand or thumbnail" catList do: [:sysCat | (SystemOrganization listAtCategoryNamed: sysCat asSymbol) do: [:symb | roots add: (Smalltalk at: symb); add: (Smalltalk at: symb) class]]. is := ImageSegment new copySmartRootsExport: roots asArray. "old way was (is := ImageSegment new copyFromRootsForExport: roots asArray)" is state = #tooBig ifTrue: [^ false]. str := ''. "considered legal to save a project that has never been entered" (is outPointers includes: world) ifTrue: [ str := str, '\Project''s own world is not in the segment.' withCRs]. str isEmpty ifFalse: [ ans := (UIManager default chooseFrom: #('Do not write file' 'Write file anyway' 'Debug') title: str). ans = 1 ifTrue: [ revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. ^ false]. ans = 3 ifTrue: [self halt: 'Segment not written']]. is writeForExportWithSources: aFileName inDirectory: aDirectory. revertSeg ifNotNil: [self projectParameterAt: #revertToMe put: revertSeg]. holder. world flapTabs do: [:ft | (ft respondsTo: #unhibernate) ifTrue: [ft unhibernate]]. is arrayOfRoots do: [:obj | obj isScriptEditorMorph ifTrue: [obj unhibernate]]. ^ true ! ----- Method: Browser>>classComment:notifying: (in category '*46Deprecated') ----- classComment: aText notifying: aPluggableTextMorph "The user has just entered aText. It may be all red (a side-effect of replacing the default comment), so remove the color if it is." | theClass cleanedText redRange | theClass := self selectedClassOrMetaClass. theClass ifNotNil: [cleanedText := aText asText. redRange := cleanedText rangeOf: TextColor red startingAt: 1. redRange size = cleanedText size ifTrue: [cleanedText removeAttribute: TextColor red from: 1 to: redRange last ]. theClass comment: aText stamp: Utilities changeStamp]. self changed: #classCommentText. ^ true! ----- Method: Browser>>defineMessage:notifying: (in category '*46Deprecated') ----- defineMessage: aString notifying: aController self deprecated: 'Use Browser >> #defineMessageFrom:notifying:. This returns a Symbol or nil, not a Boolean.'. ^ (self defineMessageFrom: aString notifying: aController) notNil.! ----- Method: Browser>>messageListSingleton (in category '*46Deprecated') ----- messageListSingleton | name | name := self selectedMessageName. ^ name ifNil: [Array new] ifNotNil: [Array with: name]! ----- Method: Browser>>optionalAnnotationHeight (in category '*46Deprecated') ----- optionalAnnotationHeight ^ 10! ----- Method: Browser>>optionalButtonHeight (in category '*46Deprecated') ----- optionalButtonHeight ^ 10! ----- Method: Browser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser. This hook is provided so that HierarchyBrowsers can indicate their restricted subset. For generic Browsers, the entire list of classes known to Smalltalk is provided, though of course that really only is accurate in the case of full system browsers." ^ Smalltalk classNames! ----- Method: CodeHolder>>abbreviatedWordingFor: (in category '*46Deprecated') ----- abbreviatedWordingFor: aButtonSelector "Answer the abbreviated form of wording, from a static table. Answer nil if there is no entry -- in which case the long form will be used on the corresponding browser button." #( (browseMethodFull 'browse') (browseSendersOfMessages 'senders') (browseMessages 'impl') (browseVersions 'vers') (methodHierarchy 'inher') (classHierarchy 'hier') (browseVariableReferences 'refs') (offerMenu 'menu')) do: [:pair | pair first == aButtonSelector ifTrue: [^ pair second]]. ^ nil! ----- Method: CodeHolder>>showingDiffsString (in category '*46Deprecated') ----- showingDiffsString "Answer a string representing whether I'm showing diffs. Not sent any more but retained so that prexisting buttons that sent this will not raise errors." ^ (self showingRegularDiffs ifTrue: [''] ifFalse: ['']), 'showDiffs'! ----- Method: CodeHolder>>toggleDiff (in category '*46Deprecated') ----- toggleDiff "Retained for backward compatibility with existing buttons in existing images" self toggleDiffing! ----- Method: HierarchyBrowser>>potentialClassNames (in category '*46Deprecated') ----- potentialClassNames "Answer the names of all the classes that could be viewed in this browser" ^ self classList collect: [:aName | aName copyWithout: $ ]! ----- Method: ScrollPane>>alwaysShowHScrollBar: (in category '*46Deprecated') ----- alwaysShowHScrollBar: bool self flag: #deprecated. self setProperty: #hScrollBarAlways toValue: bool. bool ifTrue: [self hScrollBarPolicy: #always] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>alwaysShowScrollBars: (in category '*46Deprecated') ----- alwaysShowScrollBars: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self alwaysShowHScrollBar: bool; alwaysShowVScrollBar: bool. ! ----- Method: ScrollPane>>alwaysShowVScrollBar: (in category '*46Deprecated') ----- alwaysShowVScrollBar: bool self flag: #deprecated. self setProperty: #vScrollBarAlways toValue: bool. bool ifTrue: [self vScrollBarPolicy: #always] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>hInitScrollBarTEMPORARY (in category '*46Deprecated') ----- hInitScrollBarTEMPORARY "This is called lazily before the hScrollBar is accessed in a couple of places. It is provided to transition old ScrollPanes lying around that do not have an hScrollBar. Once it has been in the image for awhile, and all ScrollPanes have an hScrollBar, this method and it's references can be removed. " "Temporary method for filein of changeset" hScrollBar ifNil: [hScrollBar := ScrollBar new model: self slotName: 'hScrollBar'. hScrollBar borderWidth: 1; borderColor: Color black. self resizeScrollBars; setScrollDeltas; hideOrShowScrollBars]. ! ----- Method: ScrollPane>>hideHScrollBarIndefinitely: (in category '*46Deprecated') ----- hideHScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool. bool ifTrue: [self hScrollBarPolicy: #never] ifFalse: [self hScrollBarPolicy: #whenNeeded]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>hideScrollBarsIndefinitely: (in category '*46Deprecated') ----- hideScrollBarsIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self hideVScrollBarIndefinitely: bool. self hideHScrollBarIndefinitely: bool. ! ----- Method: ScrollPane>>hideVScrollBarIndefinitely: (in category '*46Deprecated') ----- hideVScrollBarIndefinitely: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool. bool ifTrue: [self vScrollBarPolicy: #never] ifFalse: [self vScrollBarPolicy: #whenNeeded]. self vHideOrShowScrollBar. ! ----- Method: ScrollPane>>isAScrollbarShowing (in category '*46Deprecated') ----- isAScrollbarShowing "Return true if a either retractable scroll bar is currently showing" self flag: #deprectaed. "mt: Use #isAnyScrollbarShowing" retractableScrollBar ifFalse:[^true]. ^self hIsScrollbarShowing or: [self vIsScrollbarShowing] ! ----- Method: ScrollPane>>showHScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showHScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noHScrollBarPlease toValue: bool not. self setProperty: #hScrollBarAlways toValue: bool not. bool ifTrue: [self hScrollBarPolicy: #whenNeeded] ifFalse: [self hScrollBarPolicy: #never]. self hHideOrShowScrollBar. ! ----- Method: ScrollPane>>showScrollBarsOnlyWhenNeeded: (in category '*46Deprecated') ----- showScrollBarsOnlyWhenNeeded: bool self flag: #deprecated. self showHScrollBarOnlyWhenNeeded: bool. self showVScrollBarOnlyWhenNeeded: bool. ! ----- Method: ScrollPane>>showVScrollBarOnlyWhenNeeded: (in category '*46Deprecated') ----- showVScrollBarOnlyWhenNeeded: bool "Get rid of scroll bar for short panes that don't want it shown." self flag: #deprecated. self setProperty: #noVScrollBarPlease toValue: bool not. self setProperty: #vScrollBarAlways toValue: bool not. bool ifTrue: [self vScrollBarPolicy: #whenNeeded] ifFalse: [self vScrollBarPolicy: #never]. self vHideOrShowScrollBar. ! From commits at source.squeak.org Sat May 16 00:03:09 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 22:03:16 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.635.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.635.mcz ==================== Summary ==================== Name: Collections.spur-mt.635 Author: eem Time: 13 May 2015, 6:13:31.169 pm UUID: 024683bd-996d-483b-a731-4296aae8945c Ancestors: Collections-mt.635, Collections.spur-ul.634 Collections-mt.635 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Some debug code removed from html readwriter.. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was changed: Object subclass: #Collection instanceVariableNames: '' + classVariableNames: '' - classVariableNames: 'MutexForPicking RandomForPicking' poolDictionaries: '' category: 'Collections-Abstract'! !Collection commentStamp: '' prior: 0! I am the abstract superclass of all classes that represent a group of elements.! Item was changed: ----- Method: Collection class>>initialize (in category 'class initialization') ----- initialize "Set up a Random number generator to be used by atRandom when the user does not feel like creating his own Random generator." - RandomForPicking := Random new. - MutexForPicking := Semaphore forMutualExclusion. Smalltalk addToStartUpList: self! Item was removed: - ----- Method: Collection class>>mutexForPicking (in category 'private') ----- - mutexForPicking - ^ MutexForPicking! Item was removed: - ----- Method: Collection class>>randomForPicking (in category 'private') ----- - randomForPicking - - self deprecated: 'Use ThreadSafeRandom value instead. It''s not thread-safe to use this instance without the unaccessible MutexForPicking semaphore.'. - ^ RandomForPicking! Item was removed: - ----- Method: Collection class>>startUp (in category 'system startup') ----- - startUp - "Reseed the random generator at startup time such that a reloaded - project will not repeat a previous pseudo-random sequence when - selecting at random from a collection." - - MutexForPicking - critical: [RandomForPicking initialize]! Item was added: + ----- Method: Collection>>groupBy: (in category 'enumerating') ----- + groupBy: keyBlock + "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return them." + + | result | + result := Dictionary new. + self do: [ :each | + | key | + key := keyBlock value: each. + (result at: key ifAbsentPut: [ OrderedCollection new ]) + add: each ]. + ^result! Item was changed: ----- Method: Collection>>groupBy:having: (in category 'enumerating') ----- groupBy: keyBlock having: selectBlock "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return those collections allowed by selectBlock." + + ^(self groupBy: keyBlock) select: selectBlock! - | result | - result := Dictionary new. - self do: - [ : each | | key | - key := keyBlock value: each. - (result - at: key - ifAbsentPut: [ OrderedCollection new ]) add: each ]. - ^ result select: selectBlock! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>ignoredTags (in category 'accessing') ----- + ignoredTags + "Because we cannot process all of them." + + ^ #(body script table tr td ul ol li form select option input)! Item was added: + ----- Method: HtmlReadWriter>>isTagIgnored: (in category 'testing') ----- + isTagIgnored: aTag + + | space t | + space := aTag indexOf: Character space. + t := space > 0 + ifTrue: [aTag copyFrom: 2 to: space - 1] + ifFalse: [aTag copyFrom: 2 to: aTag size - 1]. + ^ self ignoredTags includes: t! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '=' startingAt: startIndex+attribute size. + stopIndex := aTag findString: ' ' startingAt: startIndex+1. + stopIndex = 0 ifTrue: [ + stopIndex := aTag findString: '>' startingAt: startIndex+1]. + + (aTag at: startIndex + 1) = $" + ifTrue: [startIndex := startIndex + 1]. + (aTag at: stopIndex - 1) = $" + ifTrue: [stopIndex := stopIndex - 1]. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + runArray coalesce. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processComment: (in category 'reading') ----- + processComment: aComment + ! Item was added: + ----- Method: HtmlReadWriter>>processEmptyTag: (in category 'reading') ----- + processEmptyTag: aTag + + (aTag beginsWith: '>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + (self ignoredTags includes: (aTag copyFrom: 3 to: aTag size -1)) + ifTrue: [^ self]. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processHtmlEscape: (in category 'reading') ----- + processHtmlEscape: aString + + (String htmlEntities at: (aString copyFrom: 2 to: aString size - 1) ifAbsent: []) + ifNotNil: [:char | + string add: char. + count := count + 1].! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid inComment | + lookForNewTag := true. + lookForHtmlEscape := false. + tagFound := false. + tag := OrderedCollection new. + htmlEscape := OrderedCollection new. + inComment := false. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + valid := (#(10 13) includes: character asciiValue) not. + count := count + 1. + + character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [ + inComment ifFalse: [lookForHtmlEscape := true]]. + + lookForNewTag + ifTrue: [ + lookForHtmlEscape + ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] + ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] + ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + + inComment := ((lookForNewTag not and: [tag size >= 4]) + and: [tag beginsWith: '') not]. + + ((character = $> and: [inComment not]) and: [lookForNewTag not]) ifTrue: [ + lookForNewTag := true. + (tag beginsWith: '>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + (self isTagIgnored: aTag) ifTrue: [^ self]. + + index := count - offset. + + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + (aTag beginsWith: ' 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + aString do: [:char | + (#(10 13) includes: char asciiValue) + ifTrue: [stream nextPutAll: '
'; cr] + ifFalse: [char = Character tab + ifTrue: [stream nextPutAll: '    '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]].! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + [aTextAttribute closeHtmlOn: stream] + on: MessageNotUnderstood do: []! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + [aTextAttribute openHtmlOn: stream] + on: MessageNotUnderstood do: [].! Item was added: + ----- Method: String class>>htmlEntities (in category 'accessing') ----- + htmlEntities + + ^ HtmlEntities! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:00:19 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:00:30 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.634.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.634.mcz ==================== Summary ==================== Name: Collections.spur-ul.634 Author: eem Time: 13 May 2015, 6:13:28.985 pm UUID: c9b09516-9167-494a-8dd7-3e0268f68686 Ancestors: Collections-ul.634, Collections.spur-ul.633 Collections-ul.634 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Revert the workaround from Collections-ul.633. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was changed: Object subclass: #Collection instanceVariableNames: '' + classVariableNames: '' - classVariableNames: 'MutexForPicking RandomForPicking' poolDictionaries: '' category: 'Collections-Abstract'! !Collection commentStamp: '' prior: 0! I am the abstract superclass of all classes that represent a group of elements.! Item was changed: ----- Method: Collection class>>initialize (in category 'class initialization') ----- initialize "Set up a Random number generator to be used by atRandom when the user does not feel like creating his own Random generator." - RandomForPicking := Random new. - MutexForPicking := Semaphore forMutualExclusion. Smalltalk addToStartUpList: self! Item was removed: - ----- Method: Collection class>>mutexForPicking (in category 'private') ----- - mutexForPicking - ^ MutexForPicking! Item was removed: - ----- Method: Collection class>>randomForPicking (in category 'private') ----- - randomForPicking - - self deprecated: 'Use ThreadSafeRandom value instead. It''s not thread-safe to use this instance without the unaccessible MutexForPicking semaphore.'. - ^ RandomForPicking! Item was removed: - ----- Method: Collection class>>startUp (in category 'system startup') ----- - startUp - "Reseed the random generator at startup time such that a reloaded - project will not repeat a previous pseudo-random sequence when - selecting at random from a collection." - - MutexForPicking - critical: [RandomForPicking initialize]! Item was added: + ----- Method: Collection>>groupBy: (in category 'enumerating') ----- + groupBy: keyBlock + "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return them." + + | result | + result := Dictionary new. + self do: [ :each | + | key | + key := keyBlock value: each. + (result at: key ifAbsentPut: [ OrderedCollection new ]) + add: each ]. + ^result! Item was changed: ----- Method: Collection>>groupBy:having: (in category 'enumerating') ----- groupBy: keyBlock having: selectBlock "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return those collections allowed by selectBlock." + + ^(self groupBy: keyBlock) select: selectBlock! - | result | - result := Dictionary new. - self do: - [ : each | | key | - key := keyBlock value: each. - (result - at: key - ifAbsentPut: [ OrderedCollection new ]) add: each ]. - ^ result select: selectBlock! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>ignoredTags (in category 'accessing') ----- + ignoredTags + "Because we cannot process all of them." + + ^ #(body script table tr td ul ol li form select option input)! Item was added: + ----- Method: HtmlReadWriter>>isTagIgnored: (in category 'testing') ----- + isTagIgnored: aTag + + | space t | + space := aTag indexOf: Character space. + t := space > 0 + ifTrue: [aTag copyFrom: 2 to: space - 1] + ifFalse: [aTag copyFrom: 2 to: aTag size - 1]. + ^ self ignoredTags includes: t! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + Transcript showln: aTag. + + "
" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '=' startingAt: startIndex+attribute size. + stopIndex := aTag findString: ' ' startingAt: startIndex+1. + stopIndex = 0 ifTrue: [ + stopIndex := aTag findString: '>' startingAt: startIndex+1]. + + (aTag at: startIndex + 1) = $" + ifTrue: [startIndex := startIndex + 1]. + (aTag at: stopIndex - 1) = $" + ifTrue: [stopIndex := stopIndex - 1]. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + runArray coalesce. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processComment: (in category 'reading') ----- + processComment: aComment + ! Item was added: + ----- Method: HtmlReadWriter>>processEmptyTag: (in category 'reading') ----- + processEmptyTag: aTag + + (aTag beginsWith: '>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + (self ignoredTags includes: (aTag copyFrom: 3 to: aTag size -1)) + ifTrue: [^ self]. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processHtmlEscape: (in category 'reading') ----- + processHtmlEscape: aString + + (String htmlEntities at: (aString copyFrom: 2 to: aString size - 1) ifAbsent: []) + ifNotNil: [:char | + string add: char. + count := count + 1].! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid inComment | + lookForNewTag := true. + lookForHtmlEscape := false. + tagFound := false. + tag := OrderedCollection new. + htmlEscape := OrderedCollection new. + inComment := false. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + valid := (#(10 13) includes: character asciiValue) not. + count := count + 1. + + character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [ + inComment ifFalse: [lookForHtmlEscape := true]]. + + lookForNewTag + ifTrue: [ + lookForHtmlEscape + ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] + ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] + ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + + inComment := ((lookForNewTag not and: [tag size >= 4]) + and: [tag beginsWith: '') not]. + + ((character = $> and: [inComment not]) and: [lookForNewTag not]) ifTrue: [ + lookForNewTag := true. + (tag beginsWith: '>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + (self isTagIgnored: aTag) ifTrue: [^ self]. + + index := count - offset. + + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + (aTag beginsWith: ' 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + aString do: [:char | + (#(10 13) includes: char asciiValue) + ifTrue: [stream nextPutAll: '
'; cr] + ifFalse: [char = Character tab + ifTrue: [stream nextPutAll: '    '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]].! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + [aTextAttribute closeHtmlOn: stream] + on: MessageNotUnderstood do: []! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + [aTextAttribute openHtmlOn: stream] + on: MessageNotUnderstood do: [].! Item was added: + ----- Method: String class>>htmlEntities (in category 'accessing') ----- + htmlEntities + + ^ HtmlEntities! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:00:52 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:01:01 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.633.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.633.mcz ==================== Summary ==================== Name: Collections.spur-ul.633 Author: eem Time: 12 May 2015, 3:25:41.009 pm UUID: d81620bd-3017-4b46-acec-d33261d3e299 Ancestors: Collections-ul.633, Collections.spur-ul.632 Collections-ul.633 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Don't try to use Character's ClassificationTable when the new class variables are not initialized properly. This is a possible workaround to fix the Spur bootstrap. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + AlphaNumericMask ifNotNil: [ + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + AlphaNumericMask ifNotNil: [ + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + AlphaNumericMask ifNotNil: [ + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ] ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + DigitBit ifNotNil: [ + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ] ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + LetterMask ifNotNil: [ + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ] ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + AlphaNumericMask ifNotNil: [ + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ] ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + AlphaNumericMask ifNotNil: [ + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ] ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was changed: Object subclass: #Collection instanceVariableNames: '' + classVariableNames: '' - classVariableNames: 'MutexForPicking RandomForPicking' poolDictionaries: '' category: 'Collections-Abstract'! !Collection commentStamp: '' prior: 0! I am the abstract superclass of all classes that represent a group of elements.! Item was changed: ----- Method: Collection class>>initialize (in category 'class initialization') ----- initialize "Set up a Random number generator to be used by atRandom when the user does not feel like creating his own Random generator." - RandomForPicking := Random new. - MutexForPicking := Semaphore forMutualExclusion. Smalltalk addToStartUpList: self! Item was removed: - ----- Method: Collection class>>mutexForPicking (in category 'private') ----- - mutexForPicking - ^ MutexForPicking! Item was removed: - ----- Method: Collection class>>randomForPicking (in category 'private') ----- - randomForPicking - - self deprecated: 'Use ThreadSafeRandom value instead. It''s not thread-safe to use this instance without the unaccessible MutexForPicking semaphore.'. - ^ RandomForPicking! Item was removed: - ----- Method: Collection class>>startUp (in category 'system startup') ----- - startUp - "Reseed the random generator at startup time such that a reloaded - project will not repeat a previous pseudo-random sequence when - selecting at random from a collection." - - MutexForPicking - critical: [RandomForPicking initialize]! Item was added: + ----- Method: Collection>>groupBy: (in category 'enumerating') ----- + groupBy: keyBlock + "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return them." + + | result | + result := Dictionary new. + self do: [ :each | + | key | + key := keyBlock value: each. + (result at: key ifAbsentPut: [ OrderedCollection new ]) + add: each ]. + ^result! Item was changed: ----- Method: Collection>>groupBy:having: (in category 'enumerating') ----- groupBy: keyBlock having: selectBlock "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return those collections allowed by selectBlock." + + ^(self groupBy: keyBlock) select: selectBlock! - | result | - result := Dictionary new. - self do: - [ : each | | key | - key := keyBlock value: each. - (result - at: key - ifAbsentPut: [ OrderedCollection new ]) add: each ]. - ^ result select: selectBlock! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>ignoredTags (in category 'accessing') ----- + ignoredTags + "Because we cannot process all of them." + + ^ #(body script table tr td ul ol li form select option input)! Item was added: + ----- Method: HtmlReadWriter>>isTagIgnored: (in category 'testing') ----- + isTagIgnored: aTag + + | space t | + space := aTag indexOf: Character space. + t := space > 0 + ifTrue: [aTag copyFrom: 2 to: space - 1] + ifFalse: [aTag copyFrom: 2 to: aTag size - 1]. + ^ self ignoredTags includes: t! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + Transcript showln: aTag. + + "
" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '=' startingAt: startIndex+attribute size. + stopIndex := aTag findString: ' ' startingAt: startIndex+1. + stopIndex = 0 ifTrue: [ + stopIndex := aTag findString: '>' startingAt: startIndex+1]. + + (aTag at: startIndex + 1) = $" + ifTrue: [startIndex := startIndex + 1]. + (aTag at: stopIndex - 1) = $" + ifTrue: [stopIndex := stopIndex - 1]. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + runArray coalesce. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processComment: (in category 'reading') ----- + processComment: aComment + ! Item was added: + ----- Method: HtmlReadWriter>>processEmptyTag: (in category 'reading') ----- + processEmptyTag: aTag + + (aTag beginsWith: '>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + (self ignoredTags includes: (aTag copyFrom: 3 to: aTag size -1)) + ifTrue: [^ self]. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processHtmlEscape: (in category 'reading') ----- + processHtmlEscape: aString + + (String htmlEntities at: (aString copyFrom: 2 to: aString size - 1) ifAbsent: []) + ifNotNil: [:char | + string add: char. + count := count + 1].! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid inComment | + lookForNewTag := true. + lookForHtmlEscape := false. + tagFound := false. + tag := OrderedCollection new. + htmlEscape := OrderedCollection new. + inComment := false. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + valid := (#(10 13) includes: character asciiValue) not. + count := count + 1. + + character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [ + inComment ifFalse: [lookForHtmlEscape := true]]. + + lookForNewTag + ifTrue: [ + lookForHtmlEscape + ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] + ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] + ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + + inComment := ((lookForNewTag not and: [tag size >= 4]) + and: [tag beginsWith: '') not]. + + ((character = $> and: [inComment not]) and: [lookForNewTag not]) ifTrue: [ + lookForNewTag := true. + (tag beginsWith: '>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + (self isTagIgnored: aTag) ifTrue: [^ self]. + + index := count - offset. + + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + (aTag beginsWith: ' 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + aString do: [:char | + (#(10 13) includes: char asciiValue) + ifTrue: [stream nextPutAll: '
'; cr] + ifFalse: [char = Character tab + ifTrue: [stream nextPutAll: '    '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]].! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + [aTextAttribute closeHtmlOn: stream] + on: MessageNotUnderstood do: []! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + [aTextAttribute openHtmlOn: stream] + on: MessageNotUnderstood do: [].! Item was added: + ----- Method: String class>>htmlEntities (in category 'accessing') ----- + htmlEntities + + ^ HtmlEntities! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:01:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:01:42 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.632.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.632.mcz ==================== Summary ==================== Name: Collections.spur-ul.632 Author: eem Time: 12 May 2015, 3:25:37.895 pm UUID: 22e76903-27a3-4d09-9c2d-80d738bcdbb5 Ancestors: Collections-ul.632, Collections.spur-mt.631 Collections-ul.632 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Removed MutexForPicking and RandomForPicking from Collection along with the methods referencing them, because the accessor methods were private, and they were only intended to be used for shuffling. Separated #groupBy: from #groupBy:having:. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was changed: Object subclass: #Collection instanceVariableNames: '' + classVariableNames: '' - classVariableNames: 'MutexForPicking RandomForPicking' poolDictionaries: '' category: 'Collections-Abstract'! !Collection commentStamp: '' prior: 0! I am the abstract superclass of all classes that represent a group of elements.! Item was changed: ----- Method: Collection class>>initialize (in category 'class initialization') ----- initialize "Set up a Random number generator to be used by atRandom when the user does not feel like creating his own Random generator." - RandomForPicking := Random new. - MutexForPicking := Semaphore forMutualExclusion. Smalltalk addToStartUpList: self! Item was removed: - ----- Method: Collection class>>mutexForPicking (in category 'private') ----- - mutexForPicking - ^ MutexForPicking! Item was removed: - ----- Method: Collection class>>randomForPicking (in category 'private') ----- - randomForPicking - - self deprecated: 'Use ThreadSafeRandom value instead. It''s not thread-safe to use this instance without the unaccessible MutexForPicking semaphore.'. - ^ RandomForPicking! Item was removed: - ----- Method: Collection class>>startUp (in category 'system startup') ----- - startUp - "Reseed the random generator at startup time such that a reloaded - project will not repeat a previous pseudo-random sequence when - selecting at random from a collection." - - MutexForPicking - critical: [RandomForPicking initialize]! Item was added: + ----- Method: Collection>>groupBy: (in category 'enumerating') ----- + groupBy: keyBlock + "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return them." + + | result | + result := Dictionary new. + self do: [ :each | + | key | + key := keyBlock value: each. + (result at: key ifAbsentPut: [ OrderedCollection new ]) + add: each ]. + ^result! Item was changed: ----- Method: Collection>>groupBy:having: (in category 'enumerating') ----- groupBy: keyBlock having: selectBlock "Like in SQL operation - Split the recievers contents into collections of elements for which keyBlock returns the same results, and return those collections allowed by selectBlock." + + ^(self groupBy: keyBlock) select: selectBlock! - | result | - result := Dictionary new. - self do: - [ : each | | key | - key := keyBlock value: each. - (result - at: key - ifAbsentPut: [ OrderedCollection new ]) add: each ]. - ^ result select: selectBlock! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>ignoredTags (in category 'accessing') ----- + ignoredTags + "Because we cannot process all of them." + + ^ #(body script table tr td ul ol li form select option input)! Item was added: + ----- Method: HtmlReadWriter>>isTagIgnored: (in category 'testing') ----- + isTagIgnored: aTag + + | space t | + space := aTag indexOf: Character space. + t := space > 0 + ifTrue: [aTag copyFrom: 2 to: space - 1] + ifFalse: [aTag copyFrom: 2 to: aTag size - 1]. + ^ self ignoredTags includes: t! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + Transcript showln: aTag. + + "
" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '=' startingAt: startIndex+attribute size. + stopIndex := aTag findString: ' ' startingAt: startIndex+1. + stopIndex = 0 ifTrue: [ + stopIndex := aTag findString: '>' startingAt: startIndex+1]. + + (aTag at: startIndex + 1) = $" + ifTrue: [startIndex := startIndex + 1]. + (aTag at: stopIndex - 1) = $" + ifTrue: [stopIndex := stopIndex - 1]. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + runArray coalesce. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processComment: (in category 'reading') ----- + processComment: aComment + ! Item was added: + ----- Method: HtmlReadWriter>>processEmptyTag: (in category 'reading') ----- + processEmptyTag: aTag + + (aTag beginsWith: '>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + (self ignoredTags includes: (aTag copyFrom: 3 to: aTag size -1)) + ifTrue: [^ self]. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processHtmlEscape: (in category 'reading') ----- + processHtmlEscape: aString + + (String htmlEntities at: (aString copyFrom: 2 to: aString size - 1) ifAbsent: []) + ifNotNil: [:char | + string add: char. + count := count + 1].! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid inComment | + lookForNewTag := true. + lookForHtmlEscape := false. + tagFound := false. + tag := OrderedCollection new. + htmlEscape := OrderedCollection new. + inComment := false. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + valid := (#(10 13) includes: character asciiValue) not. + count := count + 1. + + character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [ + inComment ifFalse: [lookForHtmlEscape := true]]. + + lookForNewTag + ifTrue: [ + lookForHtmlEscape + ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] + ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] + ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + + inComment := ((lookForNewTag not and: [tag size >= 4]) + and: [tag beginsWith: '') not]. + + ((character = $> and: [inComment not]) and: [lookForNewTag not]) ifTrue: [ + lookForNewTag := true. + (tag beginsWith: '>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + (self isTagIgnored: aTag) ifTrue: [^ self]. + + index := count - offset. + + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + (aTag beginsWith: ' 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + aString do: [:char | + (#(10 13) includes: char asciiValue) + ifTrue: [stream nextPutAll: '
'; cr] + ifFalse: [char = Character tab + ifTrue: [stream nextPutAll: '    '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]].! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + [aTextAttribute closeHtmlOn: stream] + on: MessageNotUnderstood do: []! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + [aTextAttribute openHtmlOn: stream] + on: MessageNotUnderstood do: [].! Item was added: + ----- Method: String class>>htmlEntities (in category 'accessing') ----- + htmlEntities + + ^ HtmlEntities! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:02:10 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:02:25 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.631.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.631.mcz ==================== Summary ==================== Name: Collections.spur-mt.631 Author: eem Time: 12 May 2015, 3:25:34.837 pm UUID: cc36677b-ba7c-43d7-9484-b393f2a2b358 Ancestors: Collections-mt.631, Collections.spur-mt.630 Collections-mt.631 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 HtmlReadWriter: support for comments added, list of ignored tags added =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>ignoredTags (in category 'accessing') ----- + ignoredTags + "Because we cannot process all of them." + + ^ #(body script table tr td ul ol li form select option input)! Item was added: + ----- Method: HtmlReadWriter>>isTagIgnored: (in category 'testing') ----- + isTagIgnored: aTag + + | space t | + space := aTag indexOf: Character space. + t := space > 0 + ifTrue: [aTag copyFrom: 2 to: space - 1] + ifFalse: [aTag copyFrom: 2 to: aTag size - 1]. + ^ self ignoredTags includes: t! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + Transcript showln: aTag. + + "
" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '=' startingAt: startIndex+attribute size. + stopIndex := aTag findString: ' ' startingAt: startIndex+1. + stopIndex = 0 ifTrue: [ + stopIndex := aTag findString: '>' startingAt: startIndex+1]. + + (aTag at: startIndex + 1) = $" + ifTrue: [startIndex := startIndex + 1]. + (aTag at: stopIndex - 1) = $" + ifTrue: [stopIndex := stopIndex - 1]. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + runArray coalesce. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processComment: (in category 'reading') ----- + processComment: aComment + ! Item was added: + ----- Method: HtmlReadWriter>>processEmptyTag: (in category 'reading') ----- + processEmptyTag: aTag + + (aTag beginsWith: '>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + (self ignoredTags includes: (aTag copyFrom: 3 to: aTag size -1)) + ifTrue: [^ self]. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processHtmlEscape: (in category 'reading') ----- + processHtmlEscape: aString + + (String htmlEntities at: (aString copyFrom: 2 to: aString size - 1) ifAbsent: []) + ifNotNil: [:char | + string add: char. + count := count + 1].! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid inComment | + lookForNewTag := true. + lookForHtmlEscape := false. + tagFound := false. + tag := OrderedCollection new. + htmlEscape := OrderedCollection new. + inComment := false. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + valid := (#(10 13) includes: character asciiValue) not. + count := count + 1. + + character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [ + inComment ifFalse: [lookForHtmlEscape := true]]. + + lookForNewTag + ifTrue: [ + lookForHtmlEscape + ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] + ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] + ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + + inComment := ((lookForNewTag not and: [tag size >= 4]) + and: [tag beginsWith: '') not]. + + ((character = $> and: [inComment not]) and: [lookForNewTag not]) ifTrue: [ + lookForNewTag := true. + (tag beginsWith: '>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + (self isTagIgnored: aTag) ifTrue: [^ self]. + + index := count - offset. + + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + (aTag beginsWith: ' 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + aString do: [:char | + (#(10 13) includes: char asciiValue) + ifTrue: [stream nextPutAll: '
'; cr] + ifFalse: [char = Character tab + ifTrue: [stream nextPutAll: '    '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]].! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + [aTextAttribute closeHtmlOn: stream] + on: MessageNotUnderstood do: []! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + [aTextAttribute openHtmlOn: stream] + on: MessageNotUnderstood do: [].! Item was added: + ----- Method: String class>>htmlEntities (in category 'accessing') ----- + htmlEntities + + ^ HtmlEntities! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:02:48 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:02:56 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.630.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.630.mcz ==================== Summary ==================== Name: Collections.spur-mt.630 Author: eem Time: 12 May 2015, 3:25:31.802 pm UUID: 39874efb-ff73-4a02-b992-97e15181eefa Ancestors: Collections-mt.630, Collections.spur-mt.629 Collections-mt.630 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 HTML escaping added to html read/writer =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + "
" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '"' startingAt: startIndex+attribute size. + stopIndex := aTag findString: '"' startingAt: startIndex+1. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processHtmlEscape: (in category 'reading') ----- + processHtmlEscape: aString + + (String htmlEntities at: (aString copyFrom: 2 to: aString size - 1) ifAbsent: []) + ifNotNil: [:char | + string add: char. + count := count + 1].! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag htmlEscape lookForNewTag lookForHtmlEscape tagFound valid | + lookForNewTag := true. + lookForHtmlEscape := false. + tagFound := false. + tag := OrderedCollection new. + htmlEscape := OrderedCollection new. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + valid := (#(10 13) includes: character asciiValue) not. + count := count + 1. + + character = $< ifTrue: [lookForNewTag := false]. + character = $& ifTrue: [lookForHtmlEscape := true]. + + lookForNewTag + ifTrue: [ + lookForHtmlEscape + ifFalse: [valid ifTrue: [string add: character] ifFalse: [offset := offset + 1]] + ifTrue: [valid ifTrue: [htmlEscape add: character]. offset := offset + 1]] + ifFalse: [valid ifTrue: [tag add: character]. offset := offset + 1]. + + character = $> ifTrue: [ + lookForNewTag := true. + "Full tag like or found." + tag second ~= $/ + ifTrue: [self processStartTag: (String withAll: tag)] + ifFalse: [self processEndTag: (String withAll: tag)]. + tagFound := true]. + + character = $; ifTrue: [ + lookForHtmlEscape := false. + self processHtmlEscape: (String withAll: htmlEscape). + htmlEscape := OrderedCollection new]]. + ! Item was added: + ----- Method: HtmlReadWriter>>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + index := count - offset. + + aTag = '
' ifTrue: [ + string add: Character cr. + count := count + 1. + ^ self]. + + "Accumulate adjacent tags." + (runStack size > 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + aString do: [:char | + (#(10 13) includes: char asciiValue) + ifTrue: [stream nextPutAll: '
'; cr] + ifFalse: [char = Character tab + ifTrue: [stream nextPutAll: '    '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]].! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + [aTextAttribute closeHtmlOn: stream] + on: MessageNotUnderstood do: []! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + [aTextAttribute openHtmlOn: stream] + on: MessageNotUnderstood do: [].! Item was added: + ----- Method: String class>>htmlEntities (in category 'accessing') ----- + htmlEntities + + ^ HtmlEntities! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:03:37 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:03:51 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.629.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.629.mcz ==================== Summary ==================== Name: Collections.spur-mt.629 Author: eem Time: 12 May 2015, 3:25:28.189 pm UUID: afe28bb0-2eea-41c7-9dfd-ef6b35465245 Ancestors: Collections-mt.629, Collections.spur-ul.628 Collections-mt.629 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Introduced a TextReadWriter (abstract) and a HtmlReadWriter (concrete) similar to ImageReadWriter. The goal is to convert foreign data into Squeak's text format. Possible additions: RtfReadWriter, DocReadWriter, ... =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was added: + TextReadWriter subclass: #HtmlReadWriter + instanceVariableNames: 'count offset runStack runArray string' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: HtmlReadWriter>>mapATag: (in category 'mapping') ----- + mapATag: aTag + + | result startIndex stopIndex attribute | + result := OrderedCollection new. + + "
" + attribute := 'href'. + startIndex := aTag findString: attribute. + startIndex > 0 ifTrue: [ + startIndex := aTag findString: '"' startingAt: startIndex+attribute size. + stopIndex := aTag findString: '"' startingAt: startIndex+1. + result add: (TextURL new url: (aTag copyFrom: startIndex+1 to: stopIndex-1))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapFontTag: (in category 'mapping') ----- + mapFontTag: aTag + + | result colorStartIndex colorStopIndex attribute | + result := OrderedCollection new. + + "" + attribute := 'color'. + colorStartIndex := aTag findString: attribute. + colorStartIndex > 0 ifTrue: [ + colorStartIndex := aTag findString: '#' startingAt: colorStartIndex+attribute size. + colorStopIndex := aTag findString: '"' startingAt: colorStartIndex+1. + result add: (TextColor color: + (Color fromString: (aTag copyFrom: colorStartIndex to: colorStopIndex-1)))]. + + ^ result! Item was added: + ----- Method: HtmlReadWriter>>mapTagToAttribute: (in category 'mapping') ----- + mapTagToAttribute: aTag + + aTag = '' ifTrue: [^ {TextEmphasis bold}]. + aTag = '' ifTrue: [^ {TextEmphasis italic}]. + aTag = '' ifTrue: [^ {TextEmphasis underlined}]. + "aTag = '' ifTrue: [^ {TextFontReference toFont: Preferences standardCodeFont}]." + (aTag beginsWith: '>nextPutText: (in category 'accessing') ----- + nextPutText: aText + + aText runs + withStartStopAndValueDo: [:start :stop :attributes | + | att str | + att := aText attributesAt: start. + str := aText string copyFrom: start to: stop. + + att do: [:each | self writeStartTagFor: each]. + self writeContent: str. + att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>nextText (in category 'accessing') ----- + nextText + + count := 0. + offset := 0. "To ignore characters in the input string that are used by tags." + + runStack := Stack new. + + runArray := RunArray new. + string := OrderedCollection new. + + "{text attributes. start index. end index. number of open tags}" + runStack push: {OrderedCollection new. 1. nil. 0}. + + [stream atEnd] whileFalse: [self processNextTag]. + self processRunStackTop. "Add last run." + + string := String withAll: string. + + ^ Text + string: string + runs: runArray! Item was added: + ----- Method: HtmlReadWriter>>processEndTag: (in category 'reading') ----- + processEndTag: aTag + + | index | + index := count - offset. + + "De-Accumulate adjacent tags." + runStack top at: 4 put: runStack top fourth - 1. + runStack top fourth > 0 + ifTrue: [^ self "not yet"]. + + self processRunStackTop. + + runStack pop. + runStack top at: 2 put: index + 1.! Item was added: + ----- Method: HtmlReadWriter>>processNextTag (in category 'reading') ----- + processNextTag + + | tag lookForNewTag escapeNextCharacter tagFound | + lookForNewTag := true. + tagFound := false. + tag := OrderedCollection new. + escapeNextCharacter := false. + + [stream atEnd not and: [tagFound not]] whileTrue: [ + | character | + character := stream next. + count := count + 1. + + escapeNextCharacter + ifTrue: [string add: character. escapeNextCharacter := false] + ifFalse: [ + character = $\ + ifTrue: [offset := offset + 1. escapeNextCharacter := true] + ifFalse: [ + character = $< ifTrue: [lookForNewTag := false]. + character = $> ifTrue: [lookForNewTag := true]. + + (lookForNewTag and: [character ~= $>]) + ifTrue: [string add: character] + ifFalse: [tag add: character. offset := offset + 1].. + + (tag notEmpty and: [tag last = $>]) ifTrue: [ + "Full tag like or found." + tag second ~= $/ + ifTrue: [self processStartTag: (String withAll: tag)] + ifFalse: [self processEndTag: (String withAll: tag)]. + tagFound := true]]]]. + ! Item was added: + ----- Method: HtmlReadWriter>>processRunStackTop (in category 'reading') ----- + processRunStackTop + "Write accumulated attributes to run array." + + | index start end attrs | + index := count - offset. + + "Set end index." + runStack top at: 3 put: index. + "Write to run array." + start := runStack top second. + end := runStack top third. + attrs := runStack top first. + runArray + addLast: attrs asArray + times: end - start + 1.! Item was added: + ----- Method: HtmlReadWriter>>processStartTag: (in category 'reading') ----- + processStartTag: aTag + + | index | + index := count - offset. + + "Accumulate adjacent tags." + (runStack size > 1 and: [runStack top second = (index + 1) "= adjacent start tags"]) + ifTrue: [ + runStack top at: 1 put: (runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself). + runStack top at: 4 put: (runStack top fourth + 1). "increase number of open tags" + ^self]. + + self processRunStackTop. + + "Remove start/end info to reuse attributes later." + runStack top at: 2 put: nil. + runStack top at: 3 put: nil. + "Copy attr list and add new attr." + runStack push: ({runStack top first copy addAll: (self mapTagToAttribute: aTag); yourself. index + 1. nil. 1}).! Item was added: + ----- Method: HtmlReadWriter>>writeContent: (in category 'writing') ----- + writeContent: aString + + | html | + html := aString. + "" + html := html copyReplaceAll: '&' with: '&'. + html := html copyReplaceAll: '>' with: '>'. + html := html copyReplaceAll: '<' with: '<'. + "" + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. + "" + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. + html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. + "" + html := html copyReplaceAll: ' + ' with: '
+ '. + html := html copyReplaceAll: ' ' with: '    '. + "" + stream nextPutAll: html! Item was added: + ----- Method: HtmlReadWriter>>writeEndTagFor: (in category 'writing') ----- + writeEndTagFor: aTextAttribute + + aTextAttribute closeHtmlOn: stream.! Item was added: + ----- Method: HtmlReadWriter>>writeStartTagFor: (in category 'writing') ----- + writeStartTagFor: aTextAttribute + + aTextAttribute openHtmlOn: stream.! Item was added: + ----- Method: String>>asTextFromHtml (in category 'converting') ----- + asTextFromHtml + "Answer a Text by interpreting the receiver as HTML." + + ^ (HtmlReadWriter on: self readStream) nextText! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was added: + ----- Method: Text>>asStringToHtml (in category 'converting') ----- + asStringToHtml + "Inverse to String >> #asTextFromHtml" + + ^ self printHtmlString! Item was removed: - ----- Method: Text>>closeHtmlAttributes:on: (in category 'html') ----- - closeHtmlAttributes: anArray on: aStream - anArray - do: [:each | each closeHtmlOn: aStream].! Item was removed: - ----- Method: Text>>openHtmlAttributes:on: (in category 'html') ----- - openHtmlAttributes: anArray on: aStream - anArray - do: [:each | each openHtmlOn: aStream ]! Item was changed: ----- Method: Text>>printHtmlOn: (in category 'html') ----- printHtmlOn: aStream + + (HtmlReadWriter on: aStream) + nextPutText: self.! - self runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := self attributesAt: start. - str := self string copyFrom: start to: stop. - "" - self openHtmlAttributes: att on: aStream. - self printStringHtml: str on: aStream. - - self closeHtmlAttributes: att on: aStream]! Item was changed: ----- Method: Text>>printHtmlString (in category 'html') ----- printHtmlString "answer a string whose characters are the html representation of the receiver" + + ^ String streamContents: [:stream | + self printHtmlOn: stream]! - | html | - html := String new writeStream. - self printHtmlOn: html. - ^ html contents! Item was removed: - ----- Method: Text>>printStringHtml:on: (in category 'html') ----- - printStringHtml: aString on: aStream - | html | - html := aString. - "" - html := html copyReplaceAll: '&' with: '&'. - html := html copyReplaceAll: '>' with: '>'. - html := html copyReplaceAll: '<' with: '<'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¦Ö' with: 'á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬©' with: 'é'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ë' with: 'í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¦ü' with: 'ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¶¬ö' with: 'ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬®¬¨¬±' with: 'ñ'. - "" - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦±' with: 'Á'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬¢' with: 'É'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¶¦º' with: 'Í'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬Æ' with: 'Ó'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¦©' with: 'Ú'. - html := html copyReplaceAll: '¬¨¬®¬¨¬é¬¨¬Ž¬¨¬·' with: 'Ñ'. - "" - html := html copyReplaceAll: ' - ' with: '
- '. - html := html copyReplaceAll: ' ' with: '    '. - "" - aStream nextPutAll: html! Item was added: + Object subclass: #TextReadWriter + instanceVariableNames: 'stream' + classVariableNames: '' + poolDictionaries: '' + category: 'Collections-Text'! Item was added: + ----- Method: TextReadWriter class>>on: (in category 'instance creation') ----- + on: stream + + ^ self new on: stream! Item was added: + ----- Method: TextReadWriter>>nextPutText: (in category 'accessing') ----- + nextPutText: aText + "Encoding aText on stream." + + self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>nextText (in category 'accessing') ----- + nextText + "Decoding a text object on stream and answer that text object." + + ^ self subclassResponsibility.! Item was added: + ----- Method: TextReadWriter>>on: (in category 'initialize-release') ----- + on: aStream + + stream := aStream.! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:04:16 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:04:24 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.628.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.628.mcz ==================== Summary ==================== Name: Collections.spur-ul.628 Author: eem Time: 12 May 2015, 3:25:25.224 pm UUID: 8bd59dd5-62cb-47bd-ae4f-214daa95aa07 Ancestors: Collections-ul.628, Collections.spur-ul.627 Collections-ul.628 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Merged Collections-ul.625. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:04:53 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:05:03 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.627.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.627.mcz ==================== Summary ==================== Name: Collections.spur-ul.627 Author: eem Time: 12 May 2015, 3:25:22.187 pm UUID: 1321d913-79db-4f82-8dbc-9e55488d0bd7 Ancestors: Collections-ul.627, Collections.spur-mt.626 Collections-ul.627 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Merged Collections-ul.624. Updated #initializeClassificationTable to save only the fully initialized table to the class variable. Reinitialize String in postscript to update the lower/uppercasing tables there too. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet newClassificationTable | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + newClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + newClassificationTable at: code + 1 put: value ]. + ClassificationTable := newClassificationTable! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable. + String initialize'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:05:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:05:39 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.626.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.626.mcz ==================== Summary ==================== Name: Collections.spur-mt.626 Author: eem Time: 12 May 2015, 3:25:19.237 pm UUID: 504c277d-2797-4ebd-a97c-3597f6592b27 Ancestors: Collections-mt.626, Collections.spur-mt.625 Collections-mt.626 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Added the (configurable) possibility to disable forced transcript updates as well as to enable a generic redirection to stdout. Only works when using the #show: or #showln: interface in Transcript. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' - Magnitude subclass: #Character - instanceVariableNames: 'value' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs aStream offs |. + (numArgs := self numArgs) >= n ifTrue: [^self]. - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. aStream := WriteStream on: (String new: 16). aStream nextPutAll: self. (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. + ^aStream contents asSymbol! - ^aStream contents asSymbol - - ! Item was changed: WriteStream subclass: #TranscriptStream instanceVariableNames: 'lastChar' + classVariableNames: 'AccessSema ForceUpdate RedirectToStdOut' - classVariableNames: 'AccessSema' poolDictionaries: '' category: 'Collections-Streams'! !TranscriptStream commentStamp: 'fbs 12/30/2013 09:53' prior: 0! This class is a much simpler implementation of Transcript protocol that supports multiple views and very simple conversion to morphic. Because it inherits from Stream, it is automatically compatible with code that is designed to write to streams.! Item was added: + ----- Method: TranscriptStream class>>forceUpdate (in category 'preferences') ----- + forceUpdate + + + ^ ForceUpdate ifNil: [true]! Item was added: + ----- Method: TranscriptStream class>>forceUpdate: (in category 'preferences') ----- + forceUpdate: aBoolean + + ForceUpdate := aBoolean.! Item was changed: + ----- Method: TranscriptStream class>>new (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>new (in category 'as yet unclassified') ----- new ^ self on: (String new: 1000) " INSTALLING: TextCollector allInstances do: [:t | t breakDependents. t become: TranscriptStream new]. TESTING: (Execute this text in a workspace) Do this first... tt := TranscriptStream new. tt openLabel: 'Transcript test 1'. Then this will open a second view -- ooooh... tt openLabel: 'Transcript test 2'. And finally make them do something... tt clear. [Sensor anyButtonPressed] whileFalse: [1 to: 20 do: [:i | tt print: (2 raisedTo: i-1); cr; endEntry]]. "! Item was changed: + ----- Method: TranscriptStream class>>newTranscript: (in category 'instance creation') ----- - ----- Method: TranscriptStream class>>newTranscript: (in category 'as yet unclassified') ----- newTranscript: aTextCollector "Store aTextCollector as the value of the system global Transcript." Smalltalk at: #Transcript put: aTextCollector! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut (in category 'preferences') ----- + redirectToStdOut + + ^ RedirectToStdOut ifNil: [false]! Item was added: + ----- Method: TranscriptStream class>>redirectToStdOut: (in category 'preferences') ----- + redirectToStdOut: aBoolean + + RedirectToStdOut := aBoolean.! Item was changed: ----- Method: TranscriptStream>>endEntry (in category 'stream extensions') ----- endEntry "Display all the characters since the last endEntry, and reset the stream" self semaphore critical:[ + self class forceUpdate + ifTrue: [self changed: #appendEntry] + ifFalse: [self changed: #appendEntryLater]. - self changed: #appendEntry. self reset. ].! Item was changed: ----- Method: TranscriptStream>>show: (in category 'stream extensions') ----- + show: anObject + "TextCollector compatibility" + + [ + self target nextPutAll: anObject asString. + self endEntry + ] on: FileWriteError do: [self class redirectToStdOut: false].! - show: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; endEntry! Item was changed: ----- Method: TranscriptStream>>showln: (in category 'stream extensions') ----- + showln: anObject + "TextCollector compatibility. Ensure a new line before inserting a message." + + [ + self target + cr; + nextPutAll: anObject asString. + self endEntry. + ] on: FileWriteError do: [self class redirectToStdOut: false].! - showln: anObject "TextCollector compatibility" - self nextPutAll: anObject asString; cr ; endEntry! Item was added: + ----- Method: TranscriptStream>>target (in category 'stream extensions') ----- + target + + ^ self class redirectToStdOut + ifTrue: [FileStream stdout] + ifFalse: [self]! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! From commits at source.squeak.org Sat May 16 01:06:03 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:06:16 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.625.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.625.mcz ==================== Summary ==================== Name: Collections.spur-ul.625 Author: eem Time: 12 May 2015, 3:25:15.619 pm UUID: da2c0e32-546b-4c50-aabf-7aabe2317e63 Ancestors: Collections-ul.625, Collections.spur-ul.624 Collections-ul.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Use the ClassificationTable in #asLowercase, #asUppercase (the obsolete behavior is gone), #isAlphaNumeric, #isDigit, #isLetter, #isLowercase and #isUppercase of Character. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + ClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + ClassificationTable at: code + 1 put: value ]! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase + "Answer the receiver's matching lowercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := (ClassificationTable at: self asInteger + 1) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toLowercaseCode: self asInteger)! - "If the receiver is uppercase, answer its matching lowercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) - ifTrue: [^ Character value: v + 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase + "Answer the receiver's matching uppercase Character." + + self asInteger > 255 ifFalse: [ + | result | + (result := ((ClassificationTable at: self asInteger + 1) bitShift: -8) bitAnd: 16rFF) > 0 + ifTrue: [ ^self class value: result ] ]. + ^self class value: (self encodedCharSet toUppercaseCode: self asInteger)! - "If the receiver is lowercase, answer its matching uppercase Character." - "A tentative implementation. Eventually this should consult the Unicode table." - - | v | - v := self charCode. - (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) - ifTrue: [^ Character value: v - 8r40]. - v < 256 ifTrue: [^self]. - ^self class value: ((value < 16r400000 - ifTrue: [Unicode] - ifFalse: [self encodedCharSet charsetClass]) - toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAlphaNumeric (in category 'testing') ----- isAlphaNumeric "Answer whether the receiver is a letter or a digit." + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: AlphaNumericMask) > 0 ]. ^self encodedCharSet isAlphaNumeric: self! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isDigit (in category 'testing') ----- isDigit + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: DigitBit) > 0 ]. ^self encodedCharSet isDigit: self. ! Item was changed: ----- Method: Character>>isLetter (in category 'testing') ----- isLetter + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LetterMask) > 0 ]. + ^self encodedCharSet isLetter: self! - ^self encodedCharSet isLetter: self. - ! Item was changed: ----- Method: Character>>isLowercase (in category 'testing') ----- isLowercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: LowercaseBit) > 0 ]. ^self encodedCharSet isLowercase: self. ! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>isUppercase (in category 'testing') ----- isUppercase + self asInteger > 255 ifFalse: [ ^((ClassificationTable at: self asInteger + 1) bitAnd: UppercaseBit) > 0 ]. ^self encodedCharSet isUppercase: self. ! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:06:38 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:06:46 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.625.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.625.mcz ==================== Summary ==================== Name: Collections.spur-mt.625 Author: eem Time: 12 May 2015, 3:25:12.547 pm UUID: bd325ddd-14af-4663-b1e5-78a5b1b618d5 Ancestors: Collections-mt.625, Collections.spur-tfel.624 Collections-mt.625 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Speed-up #endsWith: for strings. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' - Magnitude subclass: #Character - instanceVariableNames: 'value' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: String>>endsWith: (in category 'testing') ----- + endsWith: sequence + "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive." - endsWith: suffix - "Answer true if the receiver ends with the argument collection. The comparison is case-sensitive. Overridden for better performance." + | sequenceSize offset | + sequence isString ifFalse: [ ^ super endsWith: sequence ]. + ((sequenceSize := sequence size) = 0 or: [ (offset := self size - sequence size) < 0 ]) ifTrue: [ ^false ]. + 1 to: sequenceSize do: [ :index | + (sequence basicAt: index) = (self basicAt: index + offset) ifFalse: [ ^false ] ]. + ^true! - | offset | - (offset := self size - suffix size) < 0 ifTrue: [ ^false ]. - ^(self findString: suffix startingAt: offset + 1) ~= 0! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs aStream offs |. + (numArgs := self numArgs) >= n ifTrue: [^self]. - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. aStream := WriteStream on: (String new: 16). aStream nextPutAll: self. (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. + ^aStream contents asSymbol! - ^aStream contents asSymbol - - ! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! From commits at source.squeak.org Sat May 16 01:07:16 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:07:29 2015 Subject: [squeak-dev] The Trunk: Collections.spur-ul.624.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-ul.624.mcz ==================== Summary ==================== Name: Collections.spur-ul.624 Author: eem Time: 12 May 2015, 3:25:09.612 pm UUID: 866dc890-6b88-4b67-b0e0-3507e07b7581 Ancestors: Collections-ul.624, Collections.spur-tfel.623 Collections-ul.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Various improvements related to Characters and Strings. Resurrected Character's ClassificationTable - initialize it based on the actual EncodedCharSet for leadingChar 0 (Unicode) - added a bit for #isDigit - added a mask for #isAlphaNumeirc - use 0 as a tag if the uppercase or lowercase character value is greater than 255 - initialize the table in the postscript (to not infere with #initialize) Character >> #encodedCharSet assumes than leadingChar 0 means Unicode. This is hardcoded in a few methods, so why not unify it here? Simpler and faster Character >> #tokenish. Simpler and faster String >> #withoutLineEndings. Precalculate the size of the result in Symbol >> #numArgs: to avoid an extra allocation. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' + classVariableNames: 'AlphaNumericMask CharacterTable ClassificationTable DigitBit DigitValues LetterMask LowercaseBit UppercaseBit' - Magnitude subclass: #Character - instanceVariableNames: 'value' - classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>initializeClassificationTable (in category 'class initialization') ----- initializeClassificationTable + "Initialize the classification table. + The classification table is a compact encoding of upper and lower cases and digits of characters with + - bits 0-7: The lower case value of this character or 0, if its greater than 255. + - bits 8-15: The upper case value of this character or 0, if its greater than 255. + - bit 16: lowercase bit (isLowercase == true) + - bit 17: uppercase bit (isUppercase == true) + - bit 18: digit bit (isDigit == true)" + " self initializeClassificationTable " - " - Initialize the classification table. The classification table is a - compact encoding of upper and lower cases of characters with + | encodedCharSet | + "Base the table on the EncodedCharset of these characters' leadingChar - 0." + encodedCharSet := EncodedCharSet charsetAt: 0. - - bits 0-7: The lower case value of this character. - - bits 8-15: The upper case value of this character. - - bit 16: lowercase bit (e.g., isLowercase == true) - - bit 17: uppercase bit (e.g., isUppercase == true) - " - | ch1 | - LowercaseBit := 1 bitShift: 16. UppercaseBit := 1 bitShift: 17. + DigitBit := 1 bitShift: 18. + "Initialize the letter mask (e.g., isLetter == true)" + LetterMask := LowercaseBit bitOr: UppercaseBit. - "Initialize the letter bits (e.g., isLetter == true)" - LetterBits := LowercaseBit bitOr: UppercaseBit. + "Initialize the alphanumeric mask (e.g. isAlphaNumeric == true)" + AlphaNumericMask := LetterMask bitOr: DigitBit. - ClassificationTable := Array new: 256. - "Initialize the defaults (neither lower nor upper case)" - 0 to: 255 do:[:i| - ClassificationTable at: i+1 put: (i bitShift: 8) + i. - ]. + "Initialize the table based on encodedCharSet." + ClassificationTable := Array new: 256. + 0 to: 255 do: [ :code | + | isLowercase isUppercase isDigit lowercaseCode uppercaseCode value | + isLowercase := encodedCharSet isLowercaseCode: code. + isUppercase := encodedCharSet isUppercaseCode: code. + isDigit := encodedCharSet isDigitCode: code. + lowercaseCode := encodedCharSet toLowercaseCode: code. + lowercaseCode > 255 ifTrue: [ lowercaseCode := 0 ]. + uppercaseCode := encodedCharSet toUppercaseCode: code. + uppercaseCode > 255 ifTrue: [ uppercaseCode := 0 ]. + value := (uppercaseCode bitShift: 8) + lowercaseCode. + isLowercase ifTrue: [ value := value bitOr: LowercaseBit ]. + isUppercase ifTrue: [ value := value bitOr: UppercaseBit ]. + isDigit ifTrue: [ value := value bitOr: DigitBit ]. + ClassificationTable at: code + 1 put: value ]! - "Initialize character pairs (upper-lower case)" - #( - "Basic roman" - ($A $a) ($B $b) ($C $c) ($D $d) - ($E $e) ($F $f) ($G $g) ($H $h) - ($I $i) ($J $j) ($K $k) ($L $l) - ($M $m) ($N $n) ($O $o) ($P $p) - ($Q $q) ($R $r) ($S $s) ($T $t) - ($U $u) ($V $v) ($W $w) ($X $x) - ($Y $y) ($Z $z) - "International" - ($Ä $ä) ($Å $å) ($Ç $ç) ($É $é) - ($Ñ $ñ) ($Ö $ö) ($Ü $ü) ($À $à) - ($à $ã) ($Õ $õ) ($Œ $œ) ($Æ $æ) - "International - Spanish" - ($Á $á) ($Í $í) ($Ó $ó) ($Ú $ú) - "International - PLEASE CHECK" - ($È $è) ($Ì $ì) ($Ò $ò) ($Ù $ù) - ($Ë $ë) ($Ï $ï) - ($ $â) ($Ê $ê) ($Î $î) ($Ô $ô) ($Û $û) - ) do:[:pair| | ch2 | - ch1 := pair first asciiValue. - ch2 := pair last asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch2 + UppercaseBit. - ClassificationTable at: ch2+1 put: (ch1 bitShift: 8) + ch2 + LowercaseBit. - ]. - - "Initialize a few others for which we only have lower case versions." - #($ß $Ø $ø $ÿ) do:[:char| - ch1 := char asciiValue. - ClassificationTable at: ch1+1 put: (ch1 bitShift: 8) + ch1 + LowercaseBit. - ]. - ! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>encodedCharSet (in category 'accessing') ----- encodedCharSet + + self asInteger < 16r400000 ifTrue: [ ^Unicode ]. "Shortcut" - ^EncodedCharSet charsetAt: self leadingChar ! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>tokenish (in category 'testing') ----- tokenish + "Answer whether the receiver is a valid token-character--letter, digit, or colon." - "Answer whether the receiver is a valid token-character--letter, digit, or - colon." + self == $_ ifTrue: [ ^Scanner prefAllowUnderscoreSelectors ]. + ^self == $: or: [ self isAlphaNumeric ]! - ^ self == $_ - ifTrue: [ Scanner prefAllowUnderscoreSelectors ] - ifFalse: [ self == $: or: [ self isLetter or: [ self isDigit ] ] ]! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: String>>withoutLineEndings (in category 'converting') ----- withoutLineEndings + ^self withLineEndings: ' '! - ^ self withSqueakLineEndings - copyReplaceAll: String cr - with: ' ' - asTokens: false! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs offset |. + (numArgs := self numArgs) >= n ifTrue: [ ^self ]. + numArgs = 0 + ifTrue: [ offset := 1 ] + ifFalse: [ offset := 0 ]. + ^(String new: n - numArgs + offset * 5 + offset + self size streamContents: [ :stream | + stream nextPutAll: self. + numArgs = 0 ifTrue: [ stream nextPut: $:. ]. + numArgs + offset + 1 to: n do: [ :i | stream nextPutAll: 'with:' ] ]) asSymbol! - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. - aStream := WriteStream on: (String new: 16). - aStream nextPutAll: self. - - (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. - 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. - ^aStream contents asSymbol - - ! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! Item was changed: + (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'! - (PackageInfo named: 'Collections') postscript: 'LRUCache allInstances do: [ :each | each reset ]'! From commits at source.squeak.org Sat May 16 01:07:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:08:03 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.624.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.624.mcz ==================== Summary ==================== Name: Collections.spur-tfel.624 Author: eem Time: 12 May 2015, 3:25:06.732 pm UUID: c60aeb4f-cab1-4533-84e1-a982111625da Ancestors: Collections-tfel.624, Collections.spur-tfel.623 Collections-tfel.624 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 remove overrides for beginsWith: in ByteStrings and ByteSymbols, because these actually perform worse now than the generic implementation in String =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was removed: - ----- Method: ByteString>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was removed: - ----- Method: ByteSymbol>>beginsWith: (in category 'testing') ----- - beginsWith: sequence - "Answer whether the receiver begins with the given sequence. The comparison is case-sensitive. Overridden for better performance." - - | sequenceSize | - sequence class isBytes ifFalse: [ ^super beginsWith: sequence ]. - ((sequenceSize := sequence size) = 0 or: [ self size < sequenceSize ]) ifTrue: [ ^false ]. - "The following method uses a suboptimal algorithm (brute force pattern matching with O(n^2) worst case runtime), but the primitive in C is so fast (assuming large alphabets), that it's still worth using it instead of linear time pure smalltalk implementation. There are some obvious cases when the brute force algorithm is suboptimal, e.g. when the first elements don't match, so let's compare them here before using the primitive." - (self basicAt: 1) = (sequence basicAt: 1) ifFalse: [ ^false ]. - ^(self findSubstring: sequence in: self startingAt: 1 matchTable: CaseSensitiveOrder) = 1! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' - Magnitude subclass: #Character - instanceVariableNames: 'value' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs aStream offs |. + (numArgs := self numArgs) >= n ifTrue: [^self]. - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. aStream := WriteStream on: (String new: 16). aStream nextPutAll: self. (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. + ^aStream contents asSymbol! - ^aStream contents asSymbol - - ! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! From commits at source.squeak.org Sat May 16 01:08:24 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:08:37 2015 Subject: [squeak-dev] The Trunk: Collections.spur-tfel.623.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-tfel.623.mcz ==================== Summary ==================== Name: Collections.spur-tfel.623 Author: eem Time: 12 May 2015, 3:25:03.247 pm UUID: 13d53c30-8f19-44d1-b800-e6dbad20ce61 Ancestors: Collections-tfel.623, Collections.spur-nice.622 Collections-tfel.623 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 fix fallback code for ByteString>>findSubstring:in:startingAt:matchTable: when passing a starting index <= 0 =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: ByteString>>findSubstring:in:startingAt:matchTable: (in category 'comparing') ----- findSubstring: key in: body startingAt: start matchTable: matchTable "Answer the index in the string body at which the substring key first occurs, at or beyond start. The match is determined using matchTable, which can be used to effect, eg, case-insensitive matches. If no match is found, zero will be returned. The algorithm below is not optimum -- it is intended to be translated to C which will go so fast that it wont matter." | index | key size = 0 ifTrue: [^ 0]. + (start max: 1) to: body size - key size + 1 do: - start to: body size - key size + 1 do: [:startIndex | index := 1. [(matchTable at: (body at: startIndex+index-1) asciiValue + 1) = (matchTable at: (key at: index) asciiValue + 1)] whileTrue: [index = key size ifTrue: [^ startIndex]. index := index+1]]. ^ 0 " ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 1 matchTable: CaseSensitiveOrder 1 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 2 matchTable: CaseSensitiveOrder 7 ' ' findSubstring: 'abc' in: 'abcdefabcd' startingAt: 8 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseSensitiveOrder 0 ' ' findSubstring: 'abc' in: 'abcdefABcd' startingAt: 2 matchTable: CaseInsensitiveOrder 7 "! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' - Magnitude subclass: #Character - instanceVariableNames: 'value' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs aStream offs |. + (numArgs := self numArgs) >= n ifTrue: [^self]. - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. aStream := WriteStream on: (String new: 16). aStream nextPutAll: self. (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. + ^aStream contents asSymbol! - ^aStream contents asSymbol - - ! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! From commits at source.squeak.org Sat May 16 01:08:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:09:13 2015 Subject: [squeak-dev] The Trunk: Collections.spur-nice.622.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-nice.622.mcz ==================== Summary ==================== Name: Collections.spur-nice.622 Author: eem Time: 12 May 2015, 3:25:00.367 pm UUID: d56be7f0-846e-42cd-9295-74fb733e5772 Ancestors: Collections-nice.622, Collections.spur-mt.621 Collections-nice.622 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 #toBraceStack: is not used for compiling { } for so long that it's really time to get rid of it. Symbol>>numArgs: does not need to copy self into a temp var. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' - Magnitude subclass: #Character - instanceVariableNames: 'value' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was removed: - ----- Method: Collection>>toBraceStack: (in category 'private') ----- - toBraceStack: itsSize - "Push receiver's elements onto the stack of thisContext sender. Error if receiver does - not have itsSize elements or if receiver is unordered. - Do not call directly: this is called by {a. b} := ... constructs." - - self size ~= itsSize ifTrue: - [self error: 'Trying to store ', self size printString, - ' values into ', itsSize printString, ' variables.']. - thisContext sender push: itsSize fromIndexable: self! Item was changed: ----- Method: Symbol>>numArgs: (in category 'system primitives') ----- numArgs: n "Answer a string that can be used as a selector with n arguments. TODO: need to be extended to support shrinking and for selectors like #+ " + | numArgs aStream offs |. + (numArgs := self numArgs) >= n ifTrue: [^self]. - | selector numArgs aStream offs | - - selector := self. - (numArgs := selector numArgs) >= n ifTrue: [^self]. aStream := WriteStream on: (String new: 16). aStream nextPutAll: self. (numArgs = 0) ifTrue: [aStream nextPutAll: ':'. offs := 0] ifFalse: [offs := 1]. 2 to: n - numArgs + offs do: [:i | aStream nextPutAll: 'with:']. + ^aStream contents asSymbol! - ^aStream contents asSymbol - - ! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! From commits at source.squeak.org Sat May 16 01:09:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:09:36 2015 Subject: [squeak-dev] The Trunk: Collections.spur-mt.621.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-mt.621.mcz ==================== Summary ==================== Name: Collections.spur-mt.621 Author: eem Time: 12 May 2015, 3:24:57.524 pm UUID: f952d0f8-ff52-489c-9c4b-eedb76b22faf Ancestors: Collections-mt.621, Collections.spur-ul.620 Collections-mt.621 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Convenience method added to String to remove line endings/breaks from a string. =============== Diff against Collections-mt.621 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' - Magnitude subclass: #Character - instanceVariableNames: 'value' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! From commits at source.squeak.org Sat May 16 01:09:57 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:10:10 2015 Subject: [squeak-dev] The Trunk: Collections.spur-cmm.603.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-cmm.603.mcz ==================== Summary ==================== Name: Collections.spur-cmm.603 Author: eem Time: 12 May 2015, 3:24:06.611 pm UUID: dd70e0bd-a295-47e8-8a8e-f2255823c812 Ancestors: Collections-cmm.603, Collections.spur-mt.602 Collections-cmm.603 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 - Collection>>#groupBy:having: is already being used for non-Integer groups, and integerDictionary is now slower than a regular Dictionary in Spur. - PositionableStream>>#nextInto:, #next:into:, #nextInto:startingAt:, #next:into:startingAt:, and #readInto:startingAt:count require no services specific to PositionableStream. Move them up to Stream and remove the redundant implementations from various subclasses. - Let WeakArray>>#species be a regular Array instead of its own class, so that WeakArray's can be successfully compared to Arrays with equivalent contents. =============== Diff against Collections-cmm.603 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: + Magnitude immediateSubclass: #Character + instanceVariableNames: '' - Magnitude subclass: #Character - instanceVariableNames: 'value' classVariableNames: 'CharacterTable ClassificationTable DigitValues LetterBits LowercaseBit UppercaseBit' poolDictionaries: '' category: 'Collections-Strings'! + !Character commentStamp: 'eem 8/12/2014 14:53' prior: 0! + I represent a character by storing its associated Unicode as an unsigned 30-bit value. Characters are created uniquely, so that all instances of a particular Unicode are identical. My instances are encoded in tagged pointers in the VM, so called immediates, and therefore are pure immutable values. - !Character commentStamp: 'ar 4/9/2005 22:35' prior: 0! - I represent a character by storing its associated Unicode. The first 256 characters are created uniquely, so that all instances of latin1 characters ($R, for example) are identical. The code point is based on Unicode. Since Unicode is 21-bit wide character set, we have several bits available for other information. As the Unicode Standard states, a Unicode code point doesn't carry the language information. This is going to be a problem with the languages so called CJK (Chinese, Japanese, Korean. Or often CJKV including Vietnamese). Since the characters of those languages are unified and given the same code point, it is impossible to display a bare Unicode code point in an inspector or such tools. To utilize the extra available bits, we use them for identifying the languages. Since the old implementation uses the bits to identify the character encoding, the bits are sometimes called "encoding tag" or neutrally "leading char", but the bits rigidly denotes the concept of languages. + The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false.! - The other languages can have the language tag if you like. This will help to break the large default font (font set) into separately loadable chunk of fonts. However, it is open to the each native speakers and writers to decide how to define the character equality, since the same Unicode code point may have different language tag thus simple #= comparison may return false. - - I represent a character by storing its associated ASCII code (extended to 256 codes). My instances are created uniquely, so that all instances of a character ($R, for example) are identical.! Item was changed: ----- Method: Character class>>digitValue: (in category 'instance creation') ----- digitValue: x + "Answer the Character whose digit value is x. For example, + answer $9 for x=9, $0 for x=0, $A for x=10, $Z for x=35." - "Answer the Character whose digit value is x. For example, answer $9 for - x=9, $0 for x=0, $A for x=10, $Z for x=35." + | n | + n := x asInteger. + ^self value: (n < 10 ifTrue: [n + 48] ifFalse: [n + 55])! - | index | - index := x asInteger. - ^CharacterTable at: - (index < 10 - ifTrue: [48 + index] - ifFalse: [55 + index]) - + 1! Item was changed: ----- Method: Character class>>initialize (in category 'class initialization') ----- initialize + "Create the DigitsValues table." + "Character initialize" - "Create the table of unique Characters, and DigitsValues." - "Character initializeClassificationTable" - - CharacterTable ifNil: [ - "Initialize only once to ensure that byte characters are unique" - CharacterTable := Array new: 256. - 1 to: 256 do: [:i | CharacterTable at: i put: (self basicNew setValue: i - 1)]]. self initializeDigitValues! Item was changed: ----- Method: Character class>>value: (in category 'instance creation') ----- + value: anInteger - value: anInteger "Answer the Character whose value is anInteger." + + ^self primitiveFailed! - - anInteger > 255 ifTrue: [^self basicNew setValue: anInteger]. - ^ CharacterTable at: anInteger + 1. - ! Item was changed: ----- Method: Character>>< (in category 'comparing') ----- < aCharacter "Answer true if the receiver's value < aCharacter's value." + ^self asInteger < aCharacter asciiValue! - ^value < aCharacter asciiValue! Item was changed: ----- Method: Character>><= (in category 'comparing') ----- <= aCharacter "Answer true if the receiver's value <= aCharacter's value." + ^self asInteger <= aCharacter asciiValue! - ^value <= aCharacter asciiValue! Item was changed: ----- Method: Character>>= (in category 'comparing') ----- = aCharacter + "Primitive. Answer if the receiver and the argument are the + same object (have the same object pointer). Optional. See + Object documentation whatIsAPrimitive." + + ^self == aCharacter! - - ^self == aCharacter or: [ - aCharacter isCharacter and: [ aCharacter asciiValue = value ] ]! Item was changed: ----- Method: Character>>> (in category 'comparing') ----- > aCharacter "Answer true if the receiver's value > aCharacter's value." + ^self asInteger > aCharacter asciiValue! - ^value > aCharacter asciiValue! Item was changed: ----- Method: Character>>>= (in category 'comparing') ----- >= aCharacter "Answer true if the receiver's value >= aCharacter's value." + ^self asInteger >= aCharacter asciiValue! - ^value >= aCharacter asciiValue! Item was changed: ----- Method: Character>>asInteger (in category 'converting') ----- asInteger + "Answer the receiver's character code." + + ^self primitiveFailed! - "Answer the value of the receiver." - - ^value! Item was changed: ----- Method: Character>>asLowercase (in category 'converting') ----- asLowercase "If the receiver is uppercase, answer its matching lowercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r101 <= v and: [v <= 8r132]) or: [16rC0 <= v and: [v <= 16rD6]]) or: [16rD8 <= v and: [v <= 16rDE]]) ifTrue: [^ Character value: v + 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toLowercaseCode: v)! Item was changed: ----- Method: Character>>asUnicode (in category 'converting') ----- asUnicode "Answer the unicode encoding of the receiver" + self leadingChar = 0 ifTrue: [^ self asInteger]. - self leadingChar = 0 ifTrue: [^ value]. ^self encodedCharSet charsetClass convertToUnicode: self charCode ! Item was changed: ----- Method: Character>>asUppercase (in category 'converting') ----- asUppercase "If the receiver is lowercase, answer its matching uppercase Character." "A tentative implementation. Eventually this should consult the Unicode table." | v | v := self charCode. (((8r141 <= v and: [v <= 8r172]) or: [16rE0 <= v and: [v <= 16rF6]]) or: [16rF8 <= v and: [v <= 16rFE]]) ifTrue: [^ Character value: v - 8r40]. v < 256 ifTrue: [^self]. + ^self class value: ((self asInteger < 16r400000 - ^self class value: ((value < 16r400000 ifTrue: [Unicode] ifFalse: [self encodedCharSet charsetClass]) toUppercaseCode: v)! Item was changed: ----- Method: Character>>asciiValue (in category 'accessing') ----- asciiValue + "Answer the receiver's character code. + This will be ascii for characters with value <= 127, + and Unicode for those with higher values." + + ^self primitiveFailed! - "Answer the value of the receiver that represents its ascii encoding." - - ^value! Item was changed: ----- Method: Character>>charCode (in category 'accessing') ----- charCode + ^ (self asInteger bitAnd: 16r3FFFFF). - ^ (value bitAnd: 16r3FFFFF). ! Item was changed: ----- Method: Character>>clone (in category 'copying') ----- clone + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super clone! Item was changed: ----- Method: Character>>codePoint (in category 'accessing') ----- codePoint "Return the encoding value of the receiver." #Fundmntl. + ^self asInteger! - ^value! Item was removed: - ----- Method: Character>>comeFullyUpOnReload: (in category 'object fileIn') ----- - comeFullyUpOnReload: smartRefStream - "Use existing an Character. Don't use the new copy." - - ^ self class value: value! Item was changed: ----- Method: Character>>copy (in category 'copying') ----- copy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super copy! Item was changed: ----- Method: Character>>deepCopy (in category 'copying') ----- deepCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super deepCopy! Item was changed: ----- Method: Character>>digitValue (in category 'accessing') ----- digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." + self asInteger > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. + ^DigitValues at: 1 + self asInteger! - value > 16rFF ifTrue: [^self encodedCharSet digitValueOf: self]. - ^DigitValues at: 1 + value! Item was changed: ----- Method: Character>>hash (in category 'comparing') ----- hash + "Hash is reimplemented because = is implemented. + Answer the receiver's character code." + + ^self primitiveFailed! - "Hash is reimplemented because = is implemented." - - ^value! Item was changed: ----- Method: Character>>hex (in category 'printing') ----- hex + ^self asInteger printStringBase: 16! - ^value printStringBase: 16! Item was added: + ----- Method: Character>>identityHash (in category 'comparing') ----- + identityHash + "Answer the receiver's character code." + + ^self primitiveFailed! Item was changed: ----- Method: Character>>isAscii (in category 'testing') ----- isAscii + ^ self asInteger between: 0 and: 127! - ^ value between: 0 and: 127! Item was changed: ----- Method: Character>>isOctetCharacter (in category 'testing') ----- isOctetCharacter + ^ self asInteger < 256. - ^ value < 256. ! Item was changed: ----- Method: Character>>isSeparator (in category 'testing') ----- isSeparator "Answer whether the receiver is one of the separator characters--space, cr, tab, line feed, or form feed." + self asInteger = 32 ifTrue: [^true]. "space" + self asInteger = 13 ifTrue: [^true]. "cr" + self asInteger = 9 ifTrue: [^true]. "tab" + self asInteger = 10 ifTrue: [^true]. "line feed" + self asInteger = 12 ifTrue: [^true]. "form feed" - value = 32 ifTrue: [^true]. "space" - value = 13 ifTrue: [^true]. "cr" - value = 9 ifTrue: [^true]. "tab" - value = 10 ifTrue: [^true]. "line feed" - value = 12 ifTrue: [^true]. "form feed" ^false! Item was changed: ----- Method: Character>>leadingChar (in category 'accessing') ----- leadingChar "Answer the value of the 8 highest bits which is used to identify the language. This is mostly used for east asian languages CJKV as a workaround against unicode han-unification." + ^ self asInteger bitShift: -22! - ^ value bitShift: -22! Item was changed: ----- Method: Character>>macToSqueak (in category 'converting') ----- macToSqueak "Convert the receiver from MacRoman to Squeak encoding" | asciiValue | + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. asciiValue := #[ 196 197 199 201 209 214 220 225 224 226 228 227 229 231 233 232 "80-8F" 234 235 237 236 238 239 241 243 242 244 246 245 250 249 251 252 "90-9F" 134 176 162 163 167 149 182 223 174 169 153 180 168 128 198 216 "A0-AF" 129 177 138 141 165 181 142 143 144 154 157 170 186 158 230 248 "B0-BF" 191 161 172 166 131 173 178 171 187 133 160 192 195 213 140 156 "C0-CF" 150 151 147 148 145 146 247 179 255 159 185 164 139 155 188 189 "D0-DF" 135 183 130 132 137 194 202 193 203 200 205 206 207 204 211 212 "E0-EF" 190 210 218 219 217 208 136 152 175 215 221 222 184 240 253 254 ] "F0-FF" + at: self asInteger - 127. - at: value - 127. ^ Character value: asciiValue.! Item was changed: ----- Method: Character>>printOn: (in category 'printing') ----- printOn: aStream | name | + (self asInteger > 32 and: [self asInteger ~= 127]) - (value > 32 and: [value ~= 127]) ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] + ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: self asInteger ] ].! - ifFalse: [ aStream nextPutAll: self class name; nextPutAll: ' value: '; print: value ] ].! Item was removed: - ----- Method: Character>>setValue: (in category 'private') ----- - setValue: newValue - value ifNotNil:[^self error:'Characters are immutable']. - value := newValue.! Item was changed: ----- Method: Character>>shallowCopy (in category 'copying') ----- shallowCopy + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super shallowCopy! Item was changed: ----- Method: Character>>shouldBePrintedAsLiteral (in category 'testing') ----- shouldBePrintedAsLiteral + ^(self asInteger between: 33 and: 255) and: [self asInteger ~= 127]! - ^(value between: 33 and: 255) and: [value ~= 127]! Item was changed: ----- Method: Character>>squeakToMac (in category 'converting') ----- squeakToMac "Convert the receiver from Squeak to MacRoman encoding." + self asInteger < 128 ifTrue: [^ self]. + self asInteger > 255 ifTrue: [^ self]. - value < 128 ifTrue: [^ self]. - value > 255 ifTrue: [^ self]. ^ Character value: (#[ 173 176 226 196 227 201 160 224 246 228 178 220 206 179 182 183 "80-8F" 184 212 213 210 211 165 208 209 247 170 185 221 207 186 189 217 "90-9F" 202 193 162 163 219 180 195 164 172 169 187 199 194 197 168 248 "A0-AF" 161 177 198 215 171 181 166 225 252 218 188 200 222 223 240 192 "B0-BF" 203 231 229 204 128 129 174 130 233 131 230 232 237 234 235 236 "C0-CF" 245 132 241 238 239 205 133 249 175 244 242 243 134 250 251 167 "D0-DF" 136 135 137 139 138 140 190 141 143 142 144 145 147 146 148 149 "E0-EF" 253 150 152 151 153 155 154 214 191 157 156 158 159 254 255 216 "F0-FF" + ] at: self asInteger - 127) - ] at: value - 127) ! Item was changed: ----- Method: Character>>storeBinaryOn: (in category 'printing') ----- storeBinaryOn: aStream "Store the receiver on a binary (file) stream" + self asInteger < 256 - value < 256 ifTrue: [ aStream basicNextPut: self ] + ifFalse: [ aStream nextInt32Put: self asInteger ]! - ifFalse: [ aStream nextInt32Put: value ]! Item was changed: ----- Method: Character>>storeOn: (in category 'printing') ----- storeOn: aStream "Common character literals are preceded by '$', however special need to be encoded differently: for some this might be done by using one of the shortcut constructor methods for the rest we have to create them by ascii-value." | name | self shouldBePrintedAsLiteral ifTrue: [ aStream nextPut: $$; nextPut: self ] ifFalse: [ name := self class constantNameFor: self. name notNil ifTrue: [ aStream nextPutAll: self class name; space; nextPutAll: name ] ifFalse: [ aStream nextPut: $(; nextPutAll: self class name; + nextPutAll: ' value: '; print: self asInteger; nextPut: $) ] ].! - nextPutAll: ' value: '; print: value; nextPut: $) ] ].! Item was changed: ----- Method: Character>>to: (in category 'converting') ----- to: other "Answer with a collection in ascii order -- $a to: $z" + ^ (self asInteger to: other asciiValue) - ^ (value to: other asciiValue) collect: [:ascii | Character value: ascii] as: String! Item was changed: ----- Method: Character>>veryDeepCopyWith: (in category 'copying') ----- veryDeepCopyWith: deepCopier + "Answer the receiver, because Characters are unique." + ^self! - "Characters from 0 to 255 are unique, copy only the rest." - - value < 256 ifTrue: [ ^self ]. - ^super veryDeepCopyWith: deepCopier! Item was changed: ----- Method: WideString>>at: (in category 'accessing') ----- + at: index + "Answer the Character stored in the field of the receiver indexed by the + argument. Primitive. Fail if the index argument is not an Integer or is out + of bounds. Essential. See Object documentation whatIsAPrimitive." + + + ^index isInteger + ifTrue: + [self errorSubscriptBounds: index] + ifFalse: + [index isNumber + ifTrue: [self at: index asInteger] + ifFalse: [self errorNonIntegerIndex]]! - at: index - "Answer the Character stored in the field of the receiver indexed by the argument." - ^ Character value: (self wordAt: index). - ! Item was changed: ----- Method: WideString>>at:put: (in category 'accessing') ----- + at: index put: aCharacter + "Store the Character into the field of the receiver indicated by the index. + Primitive. Fail if the index is not an Integer or is out of bounds, or if the + argument is not a Character. Essential. See Object documentation whatIsAPrimitive." + + + ^aCharacter isCharacter + ifTrue: + [index isInteger + ifTrue: [self errorSubscriptBounds: index] + ifFalse: [self errorNonIntegerIndex]] + ifFalse: + [self errorImproperStore]! - at: index put: aCharacter - "Store the Character in the field of the receiver indicated by the index." - aCharacter isCharacter ifFalse:[self errorImproperStore]. - self wordAt: index put: aCharacter asInteger. - ^aCharacter! From commits at source.squeak.org Sat May 16 01:10:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 15 23:10:55 2015 Subject: [squeak-dev] The Trunk: Collections-mt.635.mcz Message-ID: Chris Muller uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-mt.635.mcz ==================== Summary ==================== Name: Collections-mt.635 Author: mt Time: 10 May 2015, 2:31:43.749 pm UUID: 5c6d47bf-db22-7a4b-b35e-24626842474b Ancestors: Collections-ul.634 Some debug code removed from html readwriter.. ==== ERROR === FileDoesNotExistException: '/home/squeaksource/sso2/ss/trunk/Collections-mt.635(mt.621).mcd' 16 May 2015 1:10:51.242 am VM: unix - Smalltalk Image: Squeak4.5 [latest update: #15015] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource/sso2 Trusted Dir /home/squeaksource/sso2/secure Untrusted Dir /home/squeaksource/sso2/My Squeak MultiByteFileStream class(StandardFileStream class)>>forceNewFileNamed: Receiver: MultiByteFileStream Arguments and temporary variables: fileName: '/home/squeaksource/sso2/ss/trunk/Collections-mt.635(mt.621).mcd' dir: nil localName: nil fullName: '/home/squeaksource/sso2/ss/trunk/Collections-mt.635(mt.621).mcd' f: nil Receiver's instance variables: superclass: StandardFileStream methodDict: a MethodDictionary(#accepts:->(MultiByteFileStream>>#accepts: "a Co...etc... format: 156 instanceVariables: #('converter' 'lineEndConvention' 'wantsLineEndConversion') organization: ('accessing' ascii binary converter converter: fileInEncodingName...etc... subclasses: nil name: #MultiByteFileStream classPool: a Dictionary(#Cr->Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-mt.635(mt.621).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 84 9 176 70 140 28 54 199 22 0 0 0 20 0 0 ...etc... filenameString: 'Collections-mt.635(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-mt.635') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-mt.635) filenameString: 'Collections-mt.635(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:10:13 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.635) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.635....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-mt.635') Arguments and temporary variables: aFileName: 'Collections-mt.635(mt.621)' aProject: The Trunk diffName: 'Collections-mt.635(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-mt.635) Receiver's instance variables: timestamp: 16 May 2015 1:10:13 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.635) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.635....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.635') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:10:34 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.635') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.635') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:10:34 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.635') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-mt.635') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read
Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-ul.625(mt.621).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 102 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-ul.625(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-ul.625') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-ul.625) filenameString: 'Collections-ul.625(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:10:44 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.625) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.625....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-ul.625') Arguments and temporary variables: aFileName: 'Collections-ul.625(mt.621)' aProject: The Trunk diffName: 'Collections-ul.625(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-ul.625) Receiver's instance variables: timestamp: 16 May 2015 1:10:44 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.625) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.625....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.625') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:11:08 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.625') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.625') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:11:08 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.625') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-ul.625') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-ul.634(ul.625).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 135 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-ul.634(ul.625).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-ul.634') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-ul.634) filenameString: 'Collections-ul.634(ul.625).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:11:23 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.634) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.634....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-ul.634') Arguments and temporary variables: aFileName: 'Collections-ul.634(ul.625)' aProject: The Trunk diffName: 'Collections-ul.634(ul.625).mcd' diffyVersion: a MCDiffyVersion(Collections-ul.634) Receiver's instance variables: timestamp: 16 May 2015 1:11:23 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.634) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.634....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.634') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:11:41 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.634') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.634') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:11:41 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.634') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-ul.634') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-ul.633(ul.625).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 148 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-ul.633(ul.625).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-ul.633') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-ul.633) filenameString: 'Collections-ul.633(ul.625).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:12:16 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.633) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.633....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-ul.633') Arguments and temporary variables: aFileName: 'Collections-ul.633(ul.625)' aProject: The Trunk diffName: 'Collections-ul.633(ul.625).mcd' diffyVersion: a MCDiffyVersion(Collections-ul.633) Receiver's instance variables: timestamp: 16 May 2015 1:12:16 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.633) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.633....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.633') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:12:37 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.633') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.633') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:12:37 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.633') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-ul.633') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-ul.632(ul.625).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 165 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-ul.632(ul.625).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-ul.632') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-ul.632) filenameString: 'Collections-ul.632(ul.625).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:12:52 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.632) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.632....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-ul.632') Arguments and temporary variables: aFileName: 'Collections-ul.632(ul.625)' aProject: The Trunk diffName: 'Collections-ul.632(ul.625).mcd' diffyVersion: a MCDiffyVersion(Collections-ul.632) Receiver's instance variables: timestamp: 16 May 2015 1:12:52 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.632) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.632....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.632') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:13:05 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.632') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.632') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:13:05 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.632') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-ul.632') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-ul.624(mt.621).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 182 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-ul.624(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-ul.624') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-ul.624) filenameString: 'Collections-ul.624(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:13:20 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.624) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.624....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-ul.624') Arguments and temporary variables: aFileName: 'Collections-ul.624(mt.621)' aProject: The Trunk diffName: 'Collections-ul.624(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-ul.624) Receiver's instance variables: timestamp: 16 May 2015 1:13:20 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.624) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.624....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.624') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:13:39 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.624') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.624') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:13:39 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.624') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-ul.624') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-mt.631(ul.625).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 199 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-mt.631(ul.625).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-mt.631') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-mt.631) filenameString: 'Collections-mt.631(ul.625).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:13:52 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.631) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.631....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-mt.631') Arguments and temporary variables: aFileName: 'Collections-mt.631(ul.625)' aProject: The Trunk diffName: 'Collections-mt.631(ul.625).mcd' diffyVersion: a MCDiffyVersion(Collections-mt.631) Receiver's instance variables: timestamp: 16 May 2015 1:13:52 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.631) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.631....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.631') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:14:09 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.631') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.631') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:14:09 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.631') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-mt.631') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-mt.630(ul.625).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 217 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-mt.630(ul.625).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-mt.630') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-mt.630) filenameString: 'Collections-mt.630(ul.625).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:14:27 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.630) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.630....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-mt.630') Arguments and temporary variables: aFileName: 'Collections-mt.630(ul.625)' aProject: The Trunk diffName: 'Collections-mt.630(ul.625).mcd' diffyVersion: a MCDiffyVersion(Collections-mt.630) Receiver's instance variables: timestamp: 16 May 2015 1:14:27 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.630) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.630....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.630') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:14:41 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.630') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.630') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:14:41 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.630') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-mt.630') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-mt.629(ul.625).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 238 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-mt.629(ul.625).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-mt.629') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-mt.629) filenameString: 'Collections-mt.629(ul.625).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:14:58 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.629) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.629....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-mt.629') Arguments and temporary variables: aFileName: 'Collections-mt.629(ul.625)' aProject: The Trunk diffName: 'Collections-mt.629(ul.625).mcd' diffyVersion: a MCDiffyVersion(Collections-mt.629) Receiver's instance variables: timestamp: 16 May 2015 1:14:58 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.629) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.629....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.629') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:15:19 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.629') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.629') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:15:19 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.629') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-mt.629') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-ul.628(ul.625).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 250 9 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-ul.628(ul.625).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-ul.628') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-ul.628) filenameString: 'Collections-ul.628(ul.625).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:15:39 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.628) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.628....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-ul.628') Arguments and temporary variables: aFileName: 'Collections-ul.628(ul.625)' aProject: The Trunk diffName: 'Collections-ul.628(ul.625).mcd' diffyVersion: a MCDiffyVersion(Collections-ul.628) Receiver's instance variables: timestamp: 16 May 2015 1:15:39 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.628) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.628....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.628') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:15:47 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.628') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.628') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:15:47 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.628') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-ul.628') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-ul.627(ul.624).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 9 10 176 70 140 28 54 199 22 0 0 0 20 0 0 ...etc... filenameString: 'Collections-ul.627(ul.624).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-ul.627') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-ul.627) filenameString: 'Collections-ul.627(ul.624).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:16:04 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.627) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.627....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-ul.627') Arguments and temporary variables: aFileName: 'Collections-ul.627(ul.624)' aProject: The Trunk diffName: 'Collections-ul.627(ul.624).mcd' diffyVersion: a MCDiffyVersion(Collections-ul.627) Receiver's instance variables: timestamp: 16 May 2015 1:16:04 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-ul.627) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-ul.627....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.627') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:16:14 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.627') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-ul.627') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:16:14 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-ul.627') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-ul.627') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-mt.626(mt.621).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 26 10 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-mt.626(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-mt.626') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-mt.626) filenameString: 'Collections-mt.626(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:16:29 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.626) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.626....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-mt.626') Arguments and temporary variables: aFileName: 'Collections-mt.626(mt.621)' aProject: The Trunk diffName: 'Collections-mt.626(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-mt.626) Receiver's instance variables: timestamp: 16 May 2015 1:16:29 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.626) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.626....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.626') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:16:45 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.626') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.626') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:16:45 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.626') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-mt.626') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-mt.625(mt.621).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 44 10 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-mt.625(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-mt.625') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-mt.625) filenameString: 'Collections-mt.625(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:17:06 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.625) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.625....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-mt.625') Arguments and temporary variables: aFileName: 'Collections-mt.625(mt.621)' aProject: The Trunk diffName: 'Collections-mt.625(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-mt.625) Receiver's instance variables: timestamp: 16 May 2015 1:17:06 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-mt.625) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-mt.625....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.625') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:17:20 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.625') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-mt.625') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:17:20 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-mt.625') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-mt.625') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-tfel.624(mt.621).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 58 10 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-tfel.624(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-tfel.624') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-tfel.624) filenameString: 'Collections-tfel.624(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:17:33 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-tfel.624) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-tfel.62...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-tfel.624') Arguments and temporary variables: aFileName: 'Collections-tfel.624(mt.621)' aProject: The Trunk diffName: 'Collections-tfel.624(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-tfel.624) Receiver's instance variables: timestamp: 16 May 2015 1:17:33 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-tfel.624) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-tfel.62...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-tfel.624') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:17:48 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-tfel.624') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-tfel.624') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:17:48 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-tfel.624') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-tfel.624') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-tfel.623(mt.621).2015-05-16.01-18-22' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Collections-tfel.623(mt.621).mcd' fileName2: 'Collections-tfel.623(mt.621).2015-05-16.01-18-22' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Collections-tfel....etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Collections-tfel.623(mt.621).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 75 10 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-tfel.623(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-tfel.623') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-tfel.623) filenameString: 'Collections-tfel.623(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:18:05 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-tfel.623) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-tfel.62...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-tfel.623') Arguments and temporary variables: aFileName: 'Collections-tfel.623(mt.621)' aProject: The Trunk diffName: 'Collections-tfel.623(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-tfel.623) Receiver's instance variables: timestamp: 16 May 2015 1:18:05 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-tfel.623) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-tfel.62...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-tfel.623') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:18:18 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-tfel.623') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-tfel.623') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:18:18 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-tfel.623') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-tfel.623') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Collections-nice.622(mt.621).2015-05-16.01-18-45' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Collections-nice.622(mt.621).mcd' fileName2: 'Collections-nice.622(mt.621).2015-05-16.01-18-45' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Collections-nice....etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Collections-nice.622(mt.621).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 86 10 176 70 140 28 54 199 22 0 0 0 20 0 0...etc... filenameString: 'Collections-nice.622(mt.621).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Collections-nice.622') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Collections-nice.622) filenameString: 'Collections-nice.622(mt.621).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:18:31 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-nice.622) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-nice.62...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Collections-nice.622') Arguments and temporary variables: aFileName: 'Collections-nice.622(mt.621)' aProject: The Trunk diffName: 'Collections-nice.622(mt.621).mcd' diffyVersion: a MCDiffyVersion(Collections-nice.622) Receiver's instance variables: timestamp: 16 May 2015 1:18:31 am author: Chris Muller versionInfo: a MCVersionInfo(Collections-nice.622) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Collections-nice.62...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-nice.622') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:18:38 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-nice.622') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Collections-nice.622') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:18:38 am stream: a WriteStream project: The Trunk version: SSVersion*('Collections-nice.622') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Collections-nice.622') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'CollectionsTests-mt.243(mt.239).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 110 10 176 70 119 203 83 61 27 0 0 0 25 0 ...etc... filenameString: 'CollectionsTests-mt.243(mt.239).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('CollectionsTests-mt.243') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(CollectionsTests-mt.243) filenameString: 'CollectionsTests-mt.243(mt.239).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:18:47 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-mt.243) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-mt...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('CollectionsTests-mt.243') Arguments and temporary variables: aFileName: 'CollectionsTests-mt.243(mt.239)' aProject: The Trunk diffName: 'CollectionsTests-mt.243(mt.239).mcd' diffyVersion: a MCDiffyVersion(CollectionsTests-mt.243) Receiver's instance variables: timestamp: 16 May 2015 1:18:47 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-mt.243) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-mt...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-mt.243') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:19:25 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-mt.243') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-mt.243') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:19:25 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-mt.243') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('CollectionsTests-mt.243') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'CollectionsTests-mt.242(mt.239).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 124 10 176 70 119 203 83 61 27 0 0 0 25 0 ...etc... filenameString: 'CollectionsTests-mt.242(mt.239).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('CollectionsTests-mt.242') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(CollectionsTests-mt.242) filenameString: 'CollectionsTests-mt.242(mt.239).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:19:32 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-mt.242) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-mt...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('CollectionsTests-mt.242') Arguments and temporary variables: aFileName: 'CollectionsTests-mt.242(mt.239)' aProject: The Trunk diffName: 'CollectionsTests-mt.242(mt.239).mcd' diffyVersion: a MCDiffyVersion(CollectionsTests-mt.242) Receiver's instance variables: timestamp: 16 May 2015 1:19:32 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-mt.242) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-mt...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-mt.242') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:19:51 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-mt.242') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-mt.242') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:19:51 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-mt.242') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('CollectionsTests-mt.242') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'CollectionsTests-mt.241(mt.239).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 139 10 176 70 119 203 83 61 27 0 0 0 25 0 ...etc... filenameString: 'CollectionsTests-mt.241(mt.239).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('CollectionsTests-mt.241') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(CollectionsTests-mt.241) filenameString: 'CollectionsTests-mt.241(mt.239).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:19:59 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-mt.241) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-mt...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('CollectionsTests-mt.241') Arguments and temporary variables: aFileName: 'CollectionsTests-mt.241(mt.239)' aProject: The Trunk diffName: 'CollectionsTests-mt.241(mt.239).mcd' diffyVersion: a MCDiffyVersion(CollectionsTests-mt.241) Receiver's instance variables: timestamp: 16 May 2015 1:19:59 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-mt.241) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-mt...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-mt.241') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:20:17 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-mt.241') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-mt.241') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:20:17 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-mt.241') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('CollectionsTests-mt.241') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'CollectionsTests-tfel.240(mt.239).2015-05-16.01-20-53' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'CollectionsTests-tfel.240(mt.239).mcd' fileName2: 'CollectionsTests-tfel.240(mt.239).2015-05-16.01-20-53' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/CollectionsTests-...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'CollectionsTests-tfel.240(mt.239).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 154 10 176 70 119 203 83 61 27 0 0 0 25 0 ...etc... filenameString: 'CollectionsTests-tfel.240(mt.239).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('CollectionsTests-tfel.240') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(CollectionsTests-tfel.240) filenameString: 'CollectionsTests-tfel.240(mt.239).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:20:26 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-tfel.240) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-tf...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('CollectionsTests-tfel.240') Arguments and temporary variables: aFileName: 'CollectionsTests-tfel.240(mt.239)' aProject: The Trunk diffName: 'CollectionsTests-tfel.240(mt.239).mcd' diffyVersion: a MCDiffyVersion(CollectionsTests-tfel.240) Receiver's instance variables: timestamp: 16 May 2015 1:20:26 am author: Chris Muller versionInfo: a MCVersionInfo(CollectionsTests-tfel.240) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'CollectionsTests-tf...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-tfel.240') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:20:50 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-tfel.240') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('CollectionsTests-tfel.240') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:20:50 am stream: a WriteStream project: The Trunk version: SSVersion*('CollectionsTests-tfel.240') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('CollectionsTests-tfel.240') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'EToys-ul.127(topa.123).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 221 10 176 70 242 247 17 247 16 0 0 0 14 0...etc... filenameString: 'EToys-ul.127(topa.123).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('EToys-ul.127') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(EToys-ul.127) filenameString: 'EToys-ul.127(topa.123).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:21:09 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-ul.127) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-ul.127.mcz' #...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('EToys-ul.127') Arguments and temporary variables: aFileName: 'EToys-ul.127(topa.123)' aProject: The Trunk diffName: 'EToys-ul.127(topa.123).mcd' diffyVersion: a MCDiffyVersion(EToys-ul.127) Receiver's instance variables: timestamp: 16 May 2015 1:21:09 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-ul.127) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-ul.127.mcz' #...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-ul.127') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:22:54 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-ul.127') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-ul.127') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:22:54 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-ul.127') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('EToys-ul.127') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'EToys-kfr.126(topa.123).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 19 16 176 70 242 247 17 247 16 0 0 0 14 0 ...etc... filenameString: 'EToys-kfr.126(topa.123).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('EToys-kfr.126') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(EToys-kfr.126) filenameString: 'EToys-kfr.126(topa.123).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:00:10 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-kfr.126) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-kfr.126.mcz' ...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('EToys-kfr.126') Arguments and temporary variables: aFileName: 'EToys-kfr.126(topa.123)' aProject: The Trunk diffName: 'EToys-kfr.126(topa.123).mcd' diffyVersion: a MCDiffyVersion(EToys-kfr.126) Receiver's instance variables: timestamp: 16 May 2015 2:00:10 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-kfr.126) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-kfr.126.mcz' ...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-kfr.126') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:00:32 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-kfr.126') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-kfr.126') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:00:32 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-kfr.126') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('EToys-kfr.126') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'EToys-kfr.125(topa.123).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 44 16 176 70 242 247 17 247 16 0 0 0 14 0 ...etc... filenameString: 'EToys-kfr.125(topa.123).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('EToys-kfr.125') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(EToys-kfr.125) filenameString: 'EToys-kfr.125(topa.123).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:00:49 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-kfr.125) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-kfr.125.mcz' ...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('EToys-kfr.125') Arguments and temporary variables: aFileName: 'EToys-kfr.125(topa.123)' aProject: The Trunk diffName: 'EToys-kfr.125(topa.123).mcd' diffyVersion: a MCDiffyVersion(EToys-kfr.125) Receiver's instance variables: timestamp: 16 May 2015 2:00:49 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-kfr.125) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-kfr.125.mcz' ...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-kfr.125') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:01:13 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-kfr.125') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-kfr.125') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:01:13 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-kfr.125') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('EToys-kfr.125') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'EToys-mt.124(topa.123).2015-05-16.02-01-47' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'EToys-mt.124(topa.123).mcd' fileName2: 'EToys-mt.124(topa.123).2015-05-16.02-01-47' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/EToys-mt.124(topa...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'EToys-mt.124(topa.123).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 55 16 176 70 242 247 17 247 16 0 0 0 14 0 ...etc... filenameString: 'EToys-mt.124(topa.123).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('EToys-mt.124') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(EToys-mt.124) filenameString: 'EToys-mt.124(topa.123).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:01:37 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-mt.124) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-mt.124.mcz' #...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('EToys-mt.124') Arguments and temporary variables: aFileName: 'EToys-mt.124(topa.123)' aProject: The Trunk diffName: 'EToys-mt.124(topa.123).mcd' diffyVersion: a MCDiffyVersion(EToys-mt.124) Receiver's instance variables: timestamp: 16 May 2015 2:01:37 am author: Chris Muller versionInfo: a MCVersionInfo(EToys-mt.124) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'EToys-mt.124.mcz' #...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-mt.124') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:01:43 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-mt.124') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('EToys-mt.124') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:01:43 am stream: a WriteStream project: The Trunk version: SSVersion*('EToys-mt.124') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('EToys-mt.124') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Files-cmm.144(dtl.143).2015-05-16.02-02-09' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Files-cmm.144(dtl.143).mcd' fileName2: 'Files-cmm.144(dtl.143).2015-05-16.02-02-09' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Files-cmm.144(dtl...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Files-cmm.144(dtl.143).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 68 16 176 70 235 107 114 35 16 0 0 0 14 0 ...etc... filenameString: 'Files-cmm.144(dtl.143).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Files-cmm.144') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Files-cmm.144) filenameString: 'Files-cmm.144(dtl.143).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02 am author: Chris Muller versionInfo: a MCVersionInfo(Files-cmm.144) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Files-cmm.144.mcz' ...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Files-cmm.144') Arguments and temporary variables: aFileName: 'Files-cmm.144(dtl.143)' aProject: The Trunk diffName: 'Files-cmm.144(dtl.143).mcd' diffyVersion: a MCDiffyVersion(Files-cmm.144) Receiver's instance variables: timestamp: 16 May 2015 2:02 am author: Chris Muller versionInfo: a MCVersionInfo(Files-cmm.144) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Files-cmm.144.mcz' ...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Files-cmm.144') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:05 am stream: a WriteStream project: The Trunk version: SSVersion*('Files-cmm.144') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Files-cmm.144') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:05 am stream: a WriteStream project: The Trunk version: SSVersion*('Files-cmm.144') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Files-cmm.144') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'GetText-mt.37(nice.34).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 80 16 176 70 235 78 45 125 18 0 0 0 16 0 0...etc... filenameString: 'GetText-mt.37(nice.34).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('GetText-mt.37') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(GetText-mt.37) filenameString: 'GetText-mt.37(nice.34).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:10 am author: Chris Muller versionInfo: a MCVersionInfo(GetText-mt.37) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'GetText-mt.37.mcz' ...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('GetText-mt.37') Arguments and temporary variables: aFileName: 'GetText-mt.37(nice.34)' aProject: The Trunk diffName: 'GetText-mt.37(nice.34).mcd' diffyVersion: a MCDiffyVersion(GetText-mt.37) Receiver's instance variables: timestamp: 16 May 2015 2:02:10 am author: Chris Muller versionInfo: a MCVersionInfo(GetText-mt.37) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'GetText-mt.37.mcz' ...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('GetText-mt.37') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:26 am stream: a WriteStream project: The Trunk version: SSVersion*('GetText-mt.37') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('GetText-mt.37') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:26 am stream: a WriteStream project: The Trunk version: SSVersion*('GetText-mt.37') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('GetText-mt.37') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'GetText-nice.36(nice.34).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 86 16 176 70 235 78 45 125 18 0 0 0 16 0 0...etc... filenameString: 'GetText-nice.36(nice.34).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('GetText-nice.36') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(GetText-nice.36) filenameString: 'GetText-nice.36(nice.34).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:33 am author: Chris Muller versionInfo: a MCVersionInfo(GetText-nice.36) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'GetText-nice.36.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('GetText-nice.36') Arguments and temporary variables: aFileName: 'GetText-nice.36(nice.34)' aProject: The Trunk diffName: 'GetText-nice.36(nice.34).mcd' diffyVersion: a MCDiffyVersion(GetText-nice.36) Receiver's instance variables: timestamp: 16 May 2015 2:02:33 am author: Chris Muller versionInfo: a MCVersionInfo(GetText-nice.36) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'GetText-nice.36.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('GetText-nice.36') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:40 am stream: a WriteStream project: The Trunk version: SSVersion*('GetText-nice.36') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('GetText-nice.36') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:40 am stream: a WriteStream project: The Trunk version: SSVersion*('GetText-nice.36') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('GetText-nice.36') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'GetText-kfr.35(nice.34).2015-05-16.02-02-59' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'GetText-kfr.35(nice.34).mcd' fileName2: 'GetText-kfr.35(nice.34).2015-05-16.02-02-59' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/GetText-kfr.35(ni...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'GetText-kfr.35(nice.34).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 93 16 176 70 235 78 45 125 18 0 0 0 16 0 0...etc... filenameString: 'GetText-kfr.35(nice.34).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('GetText-kfr.35') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(GetText-kfr.35) filenameString: 'GetText-kfr.35(nice.34).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:47 am author: Chris Muller versionInfo: a MCVersionInfo(GetText-kfr.35) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'GetText-kfr.35.mcz'...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('GetText-kfr.35') Arguments and temporary variables: aFileName: 'GetText-kfr.35(nice.34)' aProject: The Trunk diffName: 'GetText-kfr.35(nice.34).mcd' diffyVersion: a MCDiffyVersion(GetText-kfr.35) Receiver's instance variables: timestamp: 16 May 2015 2:02:47 am author: Chris Muller versionInfo: a MCVersionInfo(GetText-kfr.35) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'GetText-kfr.35.mcz'...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('GetText-kfr.35') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:52 am stream: a WriteStream project: The Trunk version: SSVersion*('GetText-kfr.35') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('GetText-kfr.35') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:02:52 am stream: a WriteStream project: The Trunk version: SSVersion*('GetText-kfr.35') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('GetText-kfr.35') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Graphics-mt.313(mt.311).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 145 16 176 70 15 5 251 185 19 0 0 0 17 0 0...etc... filenameString: 'Graphics-mt.313(mt.311).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Graphics-mt.313') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Graphics-mt.313) filenameString: 'Graphics-mt.313(mt.311).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:03:15 am author: Chris Muller versionInfo: a MCVersionInfo(Graphics-mt.313) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Graphics-mt.313.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Graphics-mt.313') Arguments and temporary variables: aFileName: 'Graphics-mt.313(mt.311)' aProject: The Trunk diffName: 'Graphics-mt.313(mt.311).mcd' diffyVersion: a MCDiffyVersion(Graphics-mt.313) Receiver's instance variables: timestamp: 16 May 2015 2:03:15 am author: Chris Muller versionInfo: a MCVersionInfo(Graphics-mt.313) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Graphics-mt.313.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Graphics-mt.313') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:04:32 am stream: a WriteStream project: The Trunk version: SSVersion*('Graphics-mt.313') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Graphics-mt.313') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:04:32 am stream: a WriteStream project: The Trunk version: SSVersion*('Graphics-mt.313') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Graphics-mt.313') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Graphics-mt.312(mt.311).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 14 24 176 70 15 5 251 185 19 0 0 0 17 0 0 ...etc... filenameString: 'Graphics-mt.312(mt.311).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Graphics-mt.312') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Graphics-mt.312) filenameString: 'Graphics-mt.312(mt.311).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:00:18 am author: Chris Muller versionInfo: a MCVersionInfo(Graphics-mt.312) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Graphics-mt.312.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Graphics-mt.312') Arguments and temporary variables: aFileName: 'Graphics-mt.312(mt.311)' aProject: The Trunk diffName: 'Graphics-mt.312(mt.311).mcd' diffyVersion: a MCDiffyVersion(Graphics-mt.312) Receiver's instance variables: timestamp: 16 May 2015 3:00:18 am author: Chris Muller versionInfo: a MCVersionInfo(Graphics-mt.312) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Graphics-mt.312.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Graphics-mt.312') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:00:24 am stream: a WriteStream project: The Trunk version: SSVersion*('Graphics-mt.312') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Graphics-mt.312') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:00:24 am stream: a WriteStream project: The Trunk version: SSVersion*('Graphics-mt.312') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Graphics-mt.312') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Help-Squeak-Project-kfr.24(topa.22).2015-05-16.03-01-00' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Help-Squeak-Project-kfr.24(topa.22).mcd' fileName2: 'Help-Squeak-Project-kfr.24(topa.22).2015-05-16.03-01-00' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Help-Squeak-Proje...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Help-Squeak-Project-kfr.24(topa.22).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 32 24 176 70 209 238 5 216 30 0 0 0 28 0 0...etc... filenameString: 'Help-Squeak-Project-kfr.24(topa.22).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Help-Squeak-Project-kfr.24') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Help-Squeak-Project-kfr.24) filenameString: 'Help-Squeak-Project-kfr.24(topa.22).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:00:33 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-Project-kfr.24) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-Project...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Help-Squeak-Project-kfr.24') Arguments and temporary variables: aFileName: 'Help-Squeak-Project-kfr.24(topa.22)' aProject: The Trunk diffName: 'Help-Squeak-Project-kfr.24(topa.22).mcd' diffyVersion: a MCDiffyVersion(Help-Squeak-Project-kfr.24) Receiver's instance variables: timestamp: 16 May 2015 3:00:33 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-Project-kfr.24) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-Project...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-Project-kfr.24') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:00:54 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-Project-kfr.24') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-Project-kfr.24') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:00:54 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-Project-kfr.24') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Help-Squeak-Project-kfr.24') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Help-Squeak-Project-kfr.23(topa.22).2015-05-16.03-01-20' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Help-Squeak-Project-kfr.23(topa.22).mcd' fileName2: 'Help-Squeak-Project-kfr.23(topa.22).2015-05-16.03-01-20' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Help-Squeak-Proje...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Help-Squeak-Project-kfr.23(topa.22).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 41 24 176 70 209 238 5 216 30 0 0 0 28 0 0...etc... filenameString: 'Help-Squeak-Project-kfr.23(topa.22).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Help-Squeak-Project-kfr.23') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Help-Squeak-Project-kfr.23) filenameString: 'Help-Squeak-Project-kfr.23(topa.22).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:04 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-Project-kfr.23) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-Project...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Help-Squeak-Project-kfr.23') Arguments and temporary variables: aFileName: 'Help-Squeak-Project-kfr.23(topa.22)' aProject: The Trunk diffName: 'Help-Squeak-Project-kfr.23(topa.22).mcd' diffyVersion: a MCDiffyVersion(Help-Squeak-Project-kfr.23) Receiver's instance variables: timestamp: 16 May 2015 3:01:04 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-Project-kfr.23) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-Project...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-Project-kfr.23') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:14 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-Project-kfr.23') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-Project-kfr.23') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:14 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-Project-kfr.23') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Help-Squeak-Project-kfr.23') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Help-Squeak-SWiki-mt.2(mt.1).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 53 24 176 70 244 140 117 20 28 0 0 0 26 0 ...etc... filenameString: 'Help-Squeak-SWiki-mt.2(mt.1).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Help-Squeak-SWiki-mt.2') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Help-Squeak-SWiki-mt.2) filenameString: 'Help-Squeak-SWiki-mt.2(mt.1).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:26 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-SWiki-mt.2) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-SWiki-m...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Help-Squeak-SWiki-mt.2') Arguments and temporary variables: aFileName: 'Help-Squeak-SWiki-mt.2(mt.1)' aProject: The Trunk diffName: 'Help-Squeak-SWiki-mt.2(mt.1).mcd' diffyVersion: a MCDiffyVersion(Help-Squeak-SWiki-mt.2) Receiver's instance variables: timestamp: 16 May 2015 3:01:26 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-SWiki-mt.2) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-SWiki-m...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-SWiki-mt.2') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:35 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-SWiki-mt.2') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-SWiki-mt.2') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:35 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-SWiki-mt.2') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Help-Squeak-SWiki-mt.2') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Help-Squeak-TerseGuide-kfr.5(dhn.4).2015-05-16.03-02-08' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Help-Squeak-TerseGuide-kfr.5(dhn.4).mcd' fileName2: 'Help-Squeak-TerseGuide-kfr.5(dhn.4).2015-05-16.03-02-08' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Help-Squeak-Terse...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Help-Squeak-TerseGuide-kfr.5(dhn.4).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 67 24 176 70 69 51 29 61 33 0 0 0 31 0 0 0...etc... filenameString: 'Help-Squeak-TerseGuide-kfr.5(dhn.4).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Help-Squeak-TerseGuide-kfr.5') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Help-Squeak-TerseGuide-kfr.5) filenameString: 'Help-Squeak-TerseGuide-kfr.5(dhn.4).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:49 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-TerseGuide-kfr.5) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-TerseGu...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Help-Squeak-TerseGuide-kfr.5') Arguments and temporary variables: aFileName: 'Help-Squeak-TerseGuide-kfr.5(dhn.4)' aProject: The Trunk diffName: 'Help-Squeak-TerseGuide-kfr.5(dhn.4).mcd' diffyVersion: a MCDiffyVersion(Help-Squeak-TerseGuide-kfr.5) Receiver's instance variables: timestamp: 16 May 2015 3:01:49 am author: Chris Muller versionInfo: a MCVersionInfo(Help-Squeak-TerseGuide-kfr.5) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Help-Squeak-TerseGu...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-TerseGuide-kfr.5') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-TerseGuide-kfr.5') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Help-Squeak-TerseGuide-kfr.5') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02 am stream: a WriteStream project: The Trunk version: SSVersion*('Help-Squeak-TerseGuide-kfr.5') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Help-Squeak-TerseGuide-kfr.5') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'HelpSystem-Core-mt.74(mt.68).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 82 24 176 70 201 213 141 147 26 0 0 0 24 0...etc... filenameString: 'HelpSystem-Core-mt.74(mt.68).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('HelpSystem-Core-mt.74') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(HelpSystem-Core-mt.74) filenameString: 'HelpSystem-Core-mt.74(mt.68).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02:12 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-mt.74) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-mt....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('HelpSystem-Core-mt.74') Arguments and temporary variables: aFileName: 'HelpSystem-Core-mt.74(mt.68)' aProject: The Trunk diffName: 'HelpSystem-Core-mt.74(mt.68).mcd' diffyVersion: a MCDiffyVersion(HelpSystem-Core-mt.74) Receiver's instance variables: timestamp: 16 May 2015 3:02:12 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-mt.74) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-mt....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-mt.74') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02:28 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-mt.74') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-mt.74') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02:28 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-mt.74') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('HelpSystem-Core-mt.74') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'HelpSystem-Core-mt.73(mt.68).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 100 24 176 70 201 213 141 147 26 0 0 0 24 ...etc... filenameString: 'HelpSystem-Core-mt.73(mt.68).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('HelpSystem-Core-mt.73') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(HelpSystem-Core-mt.73) filenameString: 'HelpSystem-Core-mt.73(mt.68).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02:40 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-mt.73) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-mt....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('HelpSystem-Core-mt.73') Arguments and temporary variables: aFileName: 'HelpSystem-Core-mt.73(mt.68)' aProject: The Trunk diffName: 'HelpSystem-Core-mt.73(mt.68).mcd' diffyVersion: a MCDiffyVersion(HelpSystem-Core-mt.73) Receiver's instance variables: timestamp: 16 May 2015 3:02:40 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-mt.73) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-mt....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-mt.73') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02:56 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-mt.73') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-mt.73') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:02:56 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-mt.73') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('HelpSystem-Core-mt.73') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'HelpSystem-Core-kfr.72(mt.68).2015-05-16.03-03-33' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'HelpSystem-Core-kfr.72(mt.68).mcd' fileName2: 'HelpSystem-Core-kfr.72(mt.68).2015-05-16.03-03-33' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/HelpSystem-Core-k...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'HelpSystem-Core-kfr.72(mt.68).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 112 24 176 70 201 213 141 147 26 0 0 0 24 ...etc... filenameString: 'HelpSystem-Core-kfr.72(mt.68).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('HelpSystem-Core-kfr.72') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.72) filenameString: 'HelpSystem-Core-kfr.72(mt.68).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:03:13 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.72) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('HelpSystem-Core-kfr.72') Arguments and temporary variables: aFileName: 'HelpSystem-Core-kfr.72(mt.68)' aProject: The Trunk diffName: 'HelpSystem-Core-kfr.72(mt.68).mcd' diffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.72) Receiver's instance variables: timestamp: 16 May 2015 3:03:13 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.72) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.72') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:03:25 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.72') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.72') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:03:25 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.72') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('HelpSystem-Core-kfr.72') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'HelpSystem-Core-kfr.71(mt.68).2015-05-16.03-04-09' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'HelpSystem-Core-kfr.71(mt.68).mcd' fileName2: 'HelpSystem-Core-kfr.71(mt.68).2015-05-16.03-04-09' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/HelpSystem-Core-k...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'HelpSystem-Core-kfr.71(mt.68).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 132 24 176 70 201 213 141 147 26 0 0 0 24 ...etc... filenameString: 'HelpSystem-Core-kfr.71(mt.68).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('HelpSystem-Core-kfr.71') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.71) filenameString: 'HelpSystem-Core-kfr.71(mt.68).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:03:37 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.71) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('HelpSystem-Core-kfr.71') Arguments and temporary variables: aFileName: 'HelpSystem-Core-kfr.71(mt.68)' aProject: The Trunk diffName: 'HelpSystem-Core-kfr.71(mt.68).mcd' diffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.71) Receiver's instance variables: timestamp: 16 May 2015 3:03:37 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.71) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.71') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.71') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.71') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.71') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('HelpSystem-Core-kfr.71') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'HelpSystem-Core-kfr.70(mt.68).2015-05-16.03-04-33' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'HelpSystem-Core-kfr.70(mt.68).mcd' fileName2: 'HelpSystem-Core-kfr.70(mt.68).2015-05-16.03-04-33' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/HelpSystem-Core-k...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'HelpSystem-Core-kfr.70(mt.68).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 144 24 176 70 201 213 141 147 26 0 0 0 24 ...etc... filenameString: 'HelpSystem-Core-kfr.70(mt.68).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('HelpSystem-Core-kfr.70') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.70) filenameString: 'HelpSystem-Core-kfr.70(mt.68).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04:12 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.70) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('HelpSystem-Core-kfr.70') Arguments and temporary variables: aFileName: 'HelpSystem-Core-kfr.70(mt.68)' aProject: The Trunk diffName: 'HelpSystem-Core-kfr.70(mt.68).mcd' diffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.70) Receiver's instance variables: timestamp: 16 May 2015 3:04:12 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.70) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.70') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04:25 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.70') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.70') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04:25 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.70') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('HelpSystem-Core-kfr.70') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'HelpSystem-Core-kfr.69(mt.68).2015-05-16.03-04-59' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'HelpSystem-Core-kfr.69(mt.68).mcd' fileName2: 'HelpSystem-Core-kfr.69(mt.68).2015-05-16.03-04-59' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/HelpSystem-Core-k...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'HelpSystem-Core-kfr.69(mt.68).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 157 24 176 70 201 213 141 147 26 0 0 0 24 ...etc... filenameString: 'HelpSystem-Core-kfr.69(mt.68).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('HelpSystem-Core-kfr.69') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.69) filenameString: 'HelpSystem-Core-kfr.69(mt.68).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04:38 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.69) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('HelpSystem-Core-kfr.69') Arguments and temporary variables: aFileName: 'HelpSystem-Core-kfr.69(mt.68)' aProject: The Trunk diffName: 'HelpSystem-Core-kfr.69(mt.68).mcd' diffyVersion: a MCDiffyVersion(HelpSystem-Core-kfr.69) Receiver's instance variables: timestamp: 16 May 2015 3:04:38 am author: Chris Muller versionInfo: a MCVersionInfo(HelpSystem-Core-kfr.69) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'HelpSystem-Core-kfr...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.69') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04:51 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.69') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('HelpSystem-Core-kfr.69') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:04:51 am stream: a WriteStream project: The Trunk version: SSVersion*('HelpSystem-Core-kfr.69') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('HelpSystem-Core-kfr.69') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read >callPrimitive: (in category '*Scorch') ----- + callPrimitive: pimIndex + "V3PlusClosures: 139 10001011 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + NewsqueakV4: 249 11111001 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + ( jjjjjjj * 256) + m=1 means inlined primitive, no hard return after execution."! Item was added: + ----- Method: Integer>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + radix isInteger ifFalse: [^super floorLog: 10]. + self <= 0 ifTrue: [^DomainError signal: 'floorLog: is only defined for x > 0.0']. + ^(self numberOfDigitsInBase: radix) - 1! Item was added: + ----- Method: ScaledDecimal>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + ^self asFraction floorLog: radix! Item was changed: ----- Method: ValueHolder>>contents: (in category 'accessing') ----- contents: newContents + + contents = newContents ifTrue: [^ self]. contents := newContents. self contentsChanged! From commits at source.squeak.org Sat May 16 04:00:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 16 02:00:41 2015 Subject: [squeak-dev] The Trunk: Kernel.spur-nice.923.mcz Message-ID: Chris Muller uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel.spur-nice.923.mcz ==================== Summary ==================== Name: Kernel.spur-nice.923 Author: eem Time: 12 May 2015, 3:32:07.667 pm UUID: ed46ad2e-c619-4d7b-9dbc-7ed9afea1c15 Ancestors: Kernel-nice.923, Kernel.spur-nice.922 Kernel-nice.923 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Use an intermediate abstract Float representation (sign, exponent, significand) in order to convert single precision bits to double precision bits rather than attempting the conversion by direct bit manipulations. This lead to simpler code, because it is like a semantic bit manipulation rather than a raw bit manipulation. And this also lead to faster code on 32 bits interpreter/COG/Spur VM thanks to avoidance of LargeInteger (was Kernel-nice.893 / 24 December 2014) =============== Diff against Kernel.spur-topa.920 =============== Item was changed: ----- Method: ContextPart>>asMessage (in category 'converting') ----- asMessage + | selector args | - | sender selector args | - sender := self sender. selector := sender method selector. args := Array new: selector numArgs. 1 to: selector numArgs do: [ :i | args at: i put: (sender tempAt: i)]. ^ Message selector: selector arguments: args.! Item was added: + ----- Method: Fraction>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + | d n | + radix isInteger ifFalse: [^super floorLog: 10]. + n := numerator floorLog: radix. + d := denominator floorLog: radix. + ^(numerator * (radix raisedTo: d)) + < (denominator * (radix raisedTo: n)) + ifTrue: [n - d - 1] + ifFalse: [n - d]! Item was added: + ----- Method: InstructionClient>>callPrimitive: (in category '*Scorch') ----- + callPrimitive: pimIndex + "V3PlusClosures: 139 10001011 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + NewsqueakV4: 249 11111001 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + ( jjjjjjj * 256) + m=1 means inlined primitive, no hard return after execution."! Item was added: + ----- Method: Integer>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + radix isInteger ifFalse: [^super floorLog: 10]. + self <= 0 ifTrue: [^DomainError signal: 'floorLog: is only defined for x > 0.0']. + ^(self numberOfDigitsInBase: radix) - 1! Item was added: + ----- Method: ScaledDecimal>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + ^self asFraction floorLog: radix! From commits at source.squeak.org Sat May 16 04:01:21 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 16 02:01:37 2015 Subject: [squeak-dev] The Trunk: Kernel.spur-nice.922.mcz Message-ID: Chris Muller uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel.spur-nice.922.mcz ==================== Summary ==================== Name: Kernel.spur-nice.922 Author: eem Time: 12 May 2015, 3:32:03.095 pm UUID: 6875de48-76f2-4159-813e-aad338910ade Ancestors: Kernel-nice.922, Kernel.spur-nice.921 Kernel-nice.922 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Remove an un-necessary inst. var. shadowing (inbox Kernel-nice.745 7 March 2013) =============== Diff against Kernel.spur-topa.920 =============== Item was changed: ----- Method: ContextPart>>asMessage (in category 'converting') ----- asMessage + | selector args | - | sender selector args | - sender := self sender. selector := sender method selector. args := Array new: selector numArgs. 1 to: selector numArgs do: [ :i | args at: i put: (sender tempAt: i)]. ^ Message selector: selector arguments: args.! Item was added: + ----- Method: Fraction>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + | d n | + radix isInteger ifFalse: [^super floorLog: 10]. + n := numerator floorLog: radix. + d := denominator floorLog: radix. + ^(numerator * (radix raisedTo: d)) + < (denominator * (radix raisedTo: n)) + ifTrue: [n - d - 1] + ifFalse: [n - d]! Item was added: + ----- Method: InstructionClient>>callPrimitive: (in category '*Scorch') ----- + callPrimitive: pimIndex + "V3PlusClosures: 139 10001011 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + NewsqueakV4: 249 11111001 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + ( jjjjjjj * 256) + m=1 means inlined primitive, no hard return after execution."! Item was added: + ----- Method: Integer>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + radix isInteger ifFalse: [^super floorLog: 10]. + self <= 0 ifTrue: [^DomainError signal: 'floorLog: is only defined for x > 0.0']. + ^(self numberOfDigitsInBase: radix) - 1! Item was added: + ----- Method: ScaledDecimal>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + ^self asFraction floorLog: radix! From commits at source.squeak.org Sat May 16 04:02:15 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 16 02:02:32 2015 Subject: [squeak-dev] The Trunk: Kernel.spur-nice.921.mcz Message-ID: Chris Muller uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel.spur-nice.921.mcz ==================== Summary ==================== Name: Kernel.spur-nice.921 Author: eem Time: 12 May 2015, 3:31:59.091 pm UUID: b0a4cf6f-4899-4f58-9173-23eb5e4738c3 Ancestors: Kernel-nice.921, Kernel.spur-topa.920 Kernel-nice.921 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Provide an exact version for #floorLog: for those Number using exact arithmetic (as proposed in inbox Kernel-nice.721 / 11 December 2012). Previous version was not exact, otherwise this count would have been zero: (-300 to: -1) count: [:n | n ~= ((10 raisedTo: n) floorLog: 10)]. Note that this won't make #log: exact, and could lead to disagreement between the two functions. However, old behavior compatible with log: is still possible by passing the radix argument asFloat, so this is not a real problem. =============== Diff against Kernel.spur-topa.920 =============== Item was added: + ----- Method: Fraction>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + | d n | + radix isInteger ifFalse: [^super floorLog: 10]. + n := numerator floorLog: radix. + d := denominator floorLog: radix. + ^(numerator * (radix raisedTo: d)) + < (denominator * (radix raisedTo: n)) + ifTrue: [n - d - 1] + ifFalse: [n - d]! Item was added: + ----- Method: InstructionClient>>callPrimitive: (in category '*Scorch') ----- + callPrimitive: pimIndex + "V3PlusClosures: 139 10001011 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + NewsqueakV4: 249 11111001 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) + SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + ( jjjjjjj * 256) + m=1 means inlined primitive, no hard return after execution."! Item was added: + ----- Method: Integer>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + radix isInteger ifFalse: [^super floorLog: 10]. + self <= 0 ifTrue: [^DomainError signal: 'floorLog: is only defined for x > 0.0']. + ^(self numberOfDigitsInBase: radix) - 1! Item was added: + ----- Method: ScaledDecimal>>floorLog: (in category 'mathematical functions') ----- + floorLog: radix + "Unlike super, this version is exact when radix is integer" + + ^self asFraction floorLog: radix! From commits at source.squeak.org Sat May 16 04:03:14 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 16 02:03:32 2015 Subject: [squeak-dev] The Trunk: Kernel-mt.924.mcz Message-ID: Chris Muller uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-mt.924.mcz ==================== Summary ==================== Name: Kernel-mt.924 Author: mt Time: 3 May 2015, 10:36:03.973 am UUID: f9df7cdb-eb50-f54a-b1a5-8fcd565313b7 Ancestors: Kernel-nice.923 ValueHolder: Only notify about changed contents if contents actually changed. ==== ERROR === FileDoesNotExistException: '/home/squeaksource/sso2/ss/trunk/Kernel-mt.924(topa.920).2015-05-16.04-03-27' 16 May 2015 4:03:27.972 am VM: unix - Smalltalk Image: Squeak4.5 [latest update: #15015] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource/sso2 Trusted Dir /home/squeaksource/sso2/secure Untrusted Dir /home/squeaksource/sso2/My Squeak MultiByteFileStream class(StandardFileStream class)>>forceNewFileNamed: Receiver: MultiByteFileStream Arguments and temporary variables: fileName: '/home/squeaksource/sso2/ss/trunk/Kernel-mt.924(topa.920).2015-05-16....etc... dir: nil localName: nil fullName: '/home/squeaksource/sso2/ss/trunk/Kernel-mt.924(topa.920).2015-05-16....etc... f: nil Receiver's instance variables: superclass: StandardFileStream methodDict: a MethodDictionary(#accepts:->(MultiByteFileStream>>#accepts: "a Co...etc... format: 156 instanceVariables: #('converter' 'lineEndConvention' 'wantsLineEndConversion') organization: ('accessing' ascii binary converter converter: fileInEncodingName...etc... subclasses: nil name: #MultiByteFileStream classPool: a Dictionary(#Cr->Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Kernel-mt.924(topa.920).2015-05-16.04-03-27' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Kernel-mt.924(topa.920).mcd' fileName2: 'Kernel-mt.924(topa.920).2015-05-16.04-03-27' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Kernel-mt.924(top...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Kernel-mt.924(topa.920).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 107 32 176 70 201 84 220 34 17 0 0 0 15 0 ...etc... filenameString: 'Kernel-mt.924(topa.920).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Kernel-mt.924') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Kernel-mt.924) filenameString: 'Kernel-mt.924(topa.920).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:02:40 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-mt.924) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-mt.924.mcz' ...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Kernel-mt.924') Arguments and temporary variables: aFileName: 'Kernel-mt.924(topa.920)' aProject: The Trunk diffName: 'Kernel-mt.924(topa.920).mcd' diffyVersion: a MCDiffyVersion(Kernel-mt.924) Receiver's instance variables: timestamp: 16 May 2015 4:02:40 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-mt.924) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-mt.924.mcz' ...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-mt.924') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:03:14 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-mt.924') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-mt.924') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:03:14 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-mt.924') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Kernel-mt.924') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Kernel-nice.923(topa.920).2015-05-16.04-04-14' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Kernel-nice.923(topa.920).mcd' fileName2: 'Kernel-nice.923(topa.920).2015-05-16.04-04-14' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Kernel-nice.923(t...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Kernel-nice.923(topa.920).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 135 32 176 70 201 84 220 34 17 0 0 0 15 0 ...etc... filenameString: 'Kernel-nice.923(topa.920).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Kernel-nice.923') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Kernel-nice.923) filenameString: 'Kernel-nice.923(topa.920).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:03:33 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-nice.923) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-nice.923.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Kernel-nice.923') Arguments and temporary variables: aFileName: 'Kernel-nice.923(topa.920)' aProject: The Trunk diffName: 'Kernel-nice.923(topa.920).mcd' diffyVersion: a MCDiffyVersion(Kernel-nice.923) Receiver's instance variables: timestamp: 16 May 2015 4:03:33 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-nice.923) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-nice.923.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-nice.923') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:04:05 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-nice.923') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-nice.923') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:04:05 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-nice.923') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Kernel-nice.923') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Kernel-nice.922(topa.920).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 157 32 176 70 201 84 220 34 17 0 0 0 15 0 ...etc... filenameString: 'Kernel-nice.922(topa.920).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Kernel-nice.922') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Kernel-nice.922) filenameString: 'Kernel-nice.922(topa.920).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:04:26 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-nice.922) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-nice.922.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Kernel-nice.922') Arguments and temporary variables: aFileName: 'Kernel-nice.922(topa.920)' aProject: The Trunk diffName: 'Kernel-nice.922(topa.920).mcd' diffyVersion: a MCDiffyVersion(Kernel-nice.922) Receiver's instance variables: timestamp: 16 May 2015 4:04:26 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-nice.922) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-nice.922.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-nice.922') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:04:54 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-nice.922') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-nice.922') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:04:54 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-nice.922') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Kernel-nice.922') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Kernel-nice.921(topa.920).2015-05-16.04-05-28' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'Kernel-nice.921(topa.920).mcd' fileName2: 'Kernel-nice.921(topa.920).2015-05-16.04-05-28' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/Kernel-nice.921(t...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'Kernel-nice.921(topa.920).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 174 32 176 70 201 84 220 34 17 0 0 0 15 0 ...etc... filenameString: 'Kernel-nice.921(topa.920).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Kernel-nice.921') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Kernel-nice.921) filenameString: 'Kernel-nice.921(topa.920).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:05:17 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-nice.921) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-nice.921.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Kernel-nice.921') Arguments and temporary variables: aFileName: 'Kernel-nice.921(topa.920)' aProject: The Trunk diffName: 'Kernel-nice.921(topa.920).mcd' diffyVersion: a MCDiffyVersion(Kernel-nice.921) Receiver's instance variables: timestamp: 16 May 2015 4:05:17 am author: Chris Muller versionInfo: a MCVersionInfo(Kernel-nice.921) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Kernel-nice.921.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-nice.921') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:05:25 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-nice.921') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Kernel-nice.921') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:05:25 am stream: a WriteStream project: The Trunk version: SSVersion*('Kernel-nice.921') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Kernel-nice.921') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'KernelTests-ul.295(mt.292).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 204 32 176 70 67 62 156 116 22 0 0 0 20 0 ...etc... filenameString: 'KernelTests-ul.295(mt.292).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('KernelTests-ul.295') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(KernelTests-ul.295) filenameString: 'KernelTests-ul.295(mt.292).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:05:36 am author: Chris Muller versionInfo: a MCVersionInfo(KernelTests-ul.295) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'KernelTests-ul.295....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('KernelTests-ul.295') Arguments and temporary variables: aFileName: 'KernelTests-ul.295(mt.292)' aProject: The Trunk diffName: 'KernelTests-ul.295(mt.292).mcd' diffyVersion: a MCDiffyVersion(KernelTests-ul.295) Receiver's instance variables: timestamp: 16 May 2015 4:05:36 am author: Chris Muller versionInfo: a MCVersionInfo(KernelTests-ul.295) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'KernelTests-ul.295....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('KernelTests-ul.295') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:06:20 am stream: a WriteStream project: The Trunk version: SSVersion*('KernelTests-ul.295') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('KernelTests-ul.295') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:06:20 am stream: a WriteStream project: The Trunk version: SSVersion*('KernelTests-ul.295') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('KernelTests-ul.295') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'KernelTests-ul.294(mt.292).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 22 40 176 70 67 62 156 116 22 0 0 0 20 0 0...etc... filenameString: 'KernelTests-ul.294(mt.292).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('KernelTests-ul.294') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(KernelTests-ul.294) filenameString: 'KernelTests-ul.294(mt.292).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:00:08 am author: Chris Muller versionInfo: a MCVersionInfo(KernelTests-ul.294) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'KernelTests-ul.294....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('KernelTests-ul.294') Arguments and temporary variables: aFileName: 'KernelTests-ul.294(mt.292)' aProject: The Trunk diffName: 'KernelTests-ul.294(mt.292).mcd' diffyVersion: a MCDiffyVersion(KernelTests-ul.294) Receiver's instance variables: timestamp: 16 May 2015 5:00:08 am author: Chris Muller versionInfo: a MCVersionInfo(KernelTests-ul.294) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'KernelTests-ul.294....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('KernelTests-ul.294') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:00:37 am stream: a WriteStream project: The Trunk version: SSVersion*('KernelTests-ul.294') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('KernelTests-ul.294') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:00:37 am stream: a WriteStream project: The Trunk version: SSVersion*('KernelTests-ul.294') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('KernelTests-ul.294') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'KernelTests-nice.293(mt.292).2015-05-16.05-01-19' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'KernelTests-nice.293(mt.292).mcd' fileName2: 'KernelTests-nice.293(mt.292).2015-05-16.05-01-19' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/KernelTests-nice....etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'KernelTests-nice.293(mt.292).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 41 40 176 70 67 62 156 116 22 0 0 0 20 0 0...etc... filenameString: 'KernelTests-nice.293(mt.292).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('KernelTests-nice.293') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(KernelTests-nice.293) filenameString: 'KernelTests-nice.293(mt.292).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:00:54 am author: Chris Muller versionInfo: a MCVersionInfo(KernelTests-nice.293) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'KernelTests-nice.29...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('KernelTests-nice.293') Arguments and temporary variables: aFileName: 'KernelTests-nice.293(mt.292)' aProject: The Trunk diffName: 'KernelTests-nice.293(mt.292).mcd' diffyVersion: a MCDiffyVersion(KernelTests-nice.293) Receiver's instance variables: timestamp: 16 May 2015 5:00:54 am author: Chris Muller versionInfo: a MCVersionInfo(KernelTests-nice.293) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'KernelTests-nice.29...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('KernelTests-nice.293') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:01:10 am stream: a WriteStream project: The Trunk version: SSVersion*('KernelTests-nice.293') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('KernelTests-nice.293') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:01:10 am stream: a WriteStream project: The Trunk version: SSVersion*('KernelTests-nice.293') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('KernelTests-nice.293') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Monticello-mt.615(mt.612).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 100 40 176 70 177 144 223 105 21 0 0 0 19 ...etc... filenameString: 'Monticello-mt.615(mt.612).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Monticello-mt.615') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Monticello-mt.615) filenameString: 'Monticello-mt.615(mt.612).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:01:40 am author: Chris Muller versionInfo: a MCVersionInfo(Monticello-mt.615) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Monticello-mt.615.m...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Monticello-mt.615') Arguments and temporary variables: aFileName: 'Monticello-mt.615(mt.612)' aProject: The Trunk diffName: 'Monticello-mt.615(mt.612).mcd' diffyVersion: a MCDiffyVersion(Monticello-mt.615) Receiver's instance variables: timestamp: 16 May 2015 5:01:40 am author: Chris Muller versionInfo: a MCVersionInfo(Monticello-mt.615) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Monticello-mt.615.m...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Monticello-mt.615') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:02:50 am stream: a WriteStream project: The Trunk version: SSVersion*('Monticello-mt.615') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Monticello-mt.615') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:02:50 am stream: a WriteStream project: The Trunk version: SSVersion*('Monticello-mt.615') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Monticello-mt.615') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Monticello-eem.614(mt.612).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 15 48 176 70 177 144 223 105 21 0 0 0 19 0...etc... filenameString: 'Monticello-eem.614(mt.612).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Monticello-eem.614') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Monticello-eem.614) filenameString: 'Monticello-eem.614(mt.612).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:00:08 am author: Chris Muller versionInfo: a MCVersionInfo(Monticello-eem.614) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Monticello-eem.614....etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Monticello-eem.614') Arguments and temporary variables: aFileName: 'Monticello-eem.614(mt.612)' aProject: The Trunk diffName: 'Monticello-eem.614(mt.612).mcd' diffyVersion: a MCDiffyVersion(Monticello-eem.614) Receiver's instance variables: timestamp: 16 May 2015 6:00:08 am author: Chris Muller versionInfo: a MCVersionInfo(Monticello-eem.614) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Monticello-eem.614....etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Monticello-eem.614') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:00:28 am stream: a WriteStream project: The Trunk version: SSVersion*('Monticello-eem.614') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Monticello-eem.614') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:00:28 am stream: a WriteStream project: The Trunk version: SSVersion*('Monticello-eem.614') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Monticello-eem.614') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Monticello-mt.613(mt.612).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 24 48 176 70 177 144 223 105 21 0 0 0 19 0...etc... filenameString: 'Monticello-mt.613(mt.612).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Monticello-mt.613') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Monticello-mt.613) filenameString: 'Monticello-mt.613(mt.612).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:00:37 am author: Chris Muller versionInfo: a MCVersionInfo(Monticello-mt.613) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Monticello-mt.613.m...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Monticello-mt.613') Arguments and temporary variables: aFileName: 'Monticello-mt.613(mt.612)' aProject: The Trunk diffName: 'Monticello-mt.613(mt.612).mcd' diffyVersion: a MCDiffyVersion(Monticello-mt.613) Receiver's instance variables: timestamp: 16 May 2015 6:00:37 am author: Chris Muller versionInfo: a MCVersionInfo(Monticello-mt.613) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Monticello-mt.613.m...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Monticello-mt.613') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:00:46 am stream: a WriteStream project: The Trunk version: SSVersion*('Monticello-mt.613') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Monticello-mt.613') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:00:46 am stream: a WriteStream project: The Trunk version: SSVersion*('Monticello-mt.613') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Monticello-mt.613') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read >forceNewFileNamed: Receiver: MultiByteFileStream Arguments and temporary variables: fileName: '/home/squeaksource/sso2/ss/trunk/MonticelloConfigurations-eem.134(dt...etc... dir: nil localName: nil fullName: '/home/squeaksource/sso2/ss/trunk/MonticelloConfigurations-eem.134(dt...etc... f: nil Receiver's instance variables: superclass: StandardFileStream methodDict: a MethodDictionary(#accepts:->(MultiByteFileStream>>#accepts: "a Co...etc... format: 156 instanceVariables: #('converter' 'lineEndConvention' 'wantsLineEndConversion') organization: ('accessing' ascii binary converter converter: fileInEncodingName...etc... subclasses: nil name: #MultiByteFileStream classPool: a Dictionary(#Cr->Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'MonticelloConfigurations-eem.134(dtl.129).2015-05-16.06-01-14' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'MonticelloConfigurations-eem.134(dtl.129).mcd' fileName2: 'MonticelloConfigurations-eem.134(dtl.129).2015-05-16.06-01-14' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/MonticelloConfigu...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'MonticelloConfigurations-eem.134(dtl.129).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 38 48 176 70 33 229 11 190 35 0 0 0 33 0 0...etc... filenameString: 'MonticelloConfigurations-eem.134(dtl.129).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('MonticelloConfigurations-eem.134') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(MonticelloConfigurations-eem.134) filenameString: 'MonticelloConfigurations-eem.134(dtl.129).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:00:51 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-eem.134) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('MonticelloConfigurations-eem.134') Arguments and temporary variables: aFileName: 'MonticelloConfigurations-eem.134(dtl.129)' aProject: The Trunk diffName: 'MonticelloConfigurations-eem.134(dtl.129).mcd' diffyVersion: a MCDiffyVersion(MonticelloConfigurations-eem.134) Receiver's instance variables: timestamp: 16 May 2015 6:00:51 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-eem.134) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-eem.134') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:08 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-eem.134') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-eem.134') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:08 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-eem.134') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('MonticelloConfigurations-eem.134') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'MonticelloConfigurations-dtl.133(dtl.129).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 46 48 176 70 33 229 11 190 35 0 0 0 33 0 0...etc... filenameString: 'MonticelloConfigurations-dtl.133(dtl.129).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('MonticelloConfigurations-dtl.133') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(MonticelloConfigurations-dtl.133) filenameString: 'MonticelloConfigurations-dtl.133(dtl.129).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:15 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-dtl.133) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('MonticelloConfigurations-dtl.133') Arguments and temporary variables: aFileName: 'MonticelloConfigurations-dtl.133(dtl.129)' aProject: The Trunk diffName: 'MonticelloConfigurations-dtl.133(dtl.129).mcd' diffyVersion: a MCDiffyVersion(MonticelloConfigurations-dtl.133) Receiver's instance variables: timestamp: 16 May 2015 6:01:15 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-dtl.133) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-dtl.133') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:25 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-dtl.133') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-dtl.133') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:25 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-dtl.133') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('MonticelloConfigurations-dtl.133') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'MonticelloConfigurations-dtl.132(dtl.129).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 56 48 176 70 33 229 11 190 35 0 0 0 33 0 0...etc... filenameString: 'MonticelloConfigurations-dtl.132(dtl.129).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('MonticelloConfigurations-dtl.132') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(MonticelloConfigurations-dtl.132) filenameString: 'MonticelloConfigurations-dtl.132(dtl.129).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:32 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-dtl.132) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('MonticelloConfigurations-dtl.132') Arguments and temporary variables: aFileName: 'MonticelloConfigurations-dtl.132(dtl.129)' aProject: The Trunk diffName: 'MonticelloConfigurations-dtl.132(dtl.129).mcd' diffyVersion: a MCDiffyVersion(MonticelloConfigurations-dtl.132) Receiver's instance variables: timestamp: 16 May 2015 6:01:32 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-dtl.132) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-dtl.132') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:44 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-dtl.132') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-dtl.132') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:44 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-dtl.132') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('MonticelloConfigurations-dtl.132') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read >forceNewFileNamed: Receiver: MultiByteFileStream Arguments and temporary variables: fileName: '/home/squeaksource/sso2/ss/trunk/MonticelloConfigurations-dtl.131(dt...etc... dir: nil localName: nil fullName: '/home/squeaksource/sso2/ss/trunk/MonticelloConfigurations-dtl.131(dt...etc... f: nil Receiver's instance variables: superclass: StandardFileStream methodDict: a MethodDictionary(#accepts:->(MultiByteFileStream>>#accepts: "a Co...etc... format: 156 instanceVariables: #('converter' 'lineEndConvention' 'wantsLineEndConversion') organization: ('accessing' ascii binary converter converter: fileInEncodingName...etc... subclasses: nil name: #MultiByteFileStream classPool: a Dictionary(#Cr->Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'MonticelloConfigurations-dtl.131(dtl.129).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 69 48 176 70 33 229 11 190 35 0 0 0 33 0 0...etc... filenameString: 'MonticelloConfigurations-dtl.131(dtl.129).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('MonticelloConfigurations-dtl.131') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(MonticelloConfigurations-dtl.131) filenameString: 'MonticelloConfigurations-dtl.131(dtl.129).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:01:51 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-dtl.131) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('MonticelloConfigurations-dtl.131') Arguments and temporary variables: aFileName: 'MonticelloConfigurations-dtl.131(dtl.129)' aProject: The Trunk diffName: 'MonticelloConfigurations-dtl.131(dtl.129).mcd' diffyVersion: a MCDiffyVersion(MonticelloConfigurations-dtl.131) Receiver's instance variables: timestamp: 16 May 2015 6:01:51 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-dtl.131) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-dtl.131') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:02:06 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-dtl.131') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-dtl.131') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:02:06 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-dtl.131') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('MonticelloConfigurations-dtl.131') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'MonticelloConfigurations-mt.130(dtl.129).2015-05-16.06-02-35' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') UnixFileDirectory(FileDirectory)>>copyFileWithoutOverwriteConfirmationNamed:toFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: fileName1: 'MonticelloConfigurations-mt.130(dtl.129).mcd' fileName2: 'MonticelloConfigurations-mt.130(dtl.129).2015-05-16.06-02-35' file1: MultiByteFileStream: '/home/squeaksource/sso2/ss/trunk/MonticelloConfigu...etc... file2: nil Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>createBackupIn:of: Receiver: a SSFilesystem Arguments and temporary variables: aFileDirectory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' aString: 'MonticelloConfigurations-mt.130(dtl.129).mcd' Receiver's instance variables: a SSFilesystem SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 81 48 176 70 33 229 11 190 35 0 0 0 33 0 0...etc... filenameString: 'MonticelloConfigurations-mt.130(dtl.129).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('MonticelloConfigurations-mt.130') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(MonticelloConfigurations-mt.130) filenameString: 'MonticelloConfigurations-mt.130(dtl.129).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:02:14 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-mt.130) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('MonticelloConfigurations-mt.130') Arguments and temporary variables: aFileName: 'MonticelloConfigurations-mt.130(dtl.129)' aProject: The Trunk diffName: 'MonticelloConfigurations-mt.130(dtl.129).mcd' diffyVersion: a MCDiffyVersion(MonticelloConfigurations-mt.130) Receiver's instance variables: timestamp: 16 May 2015 6:02:14 am author: Chris Muller versionInfo: a MCVersionInfo(MonticelloConfigurations-mt.130) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'MonticelloConfigura...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-mt.130') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:02:27 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-mt.130') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('MonticelloConfigurations-mt.130') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:02:27 am stream: a WriteStream project: The Trunk version: SSVersion*('MonticelloConfigurations-mt.130') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('MonticelloConfigurations-mt.130') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-mt.981(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 180 48 176 70 25 235 114 143 18 0 0 0 16 0...etc... filenameString: 'Morphic-mt.981(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-mt.981') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.981) filenameString: 'Morphic-mt.981(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:02:59 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.981) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.981.mcz'...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-mt.981') Arguments and temporary variables: aFileName: 'Morphic-mt.981(kfr.908)' aProject: The Trunk diffName: 'Morphic-mt.981(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-mt.981) Receiver's instance variables: timestamp: 16 May 2015 6:02:59 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.981) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.981.mcz'...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.981') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:05:30 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.981') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.981') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 6:05:30 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.981') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-mt.981') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-kfr.980(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 50 56 176 70 25 235 114 143 18 0 0 0 16 0 ...etc... filenameString: 'Morphic-kfr.980(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-kfr.980') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-kfr.980) filenameString: 'Morphic-kfr.980(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 7:00:19 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-kfr.980) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-kfr.980.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-kfr.980') Arguments and temporary variables: aFileName: 'Morphic-kfr.980(kfr.908)' aProject: The Trunk diffName: 'Morphic-kfr.980(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-kfr.980) Receiver's instance variables: timestamp: 16 May 2015 7:00:19 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-kfr.980) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-kfr.980.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-kfr.980') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 7:01:28 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-kfr.980') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-kfr.980') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 7:01:28 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-kfr.980') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-kfr.980') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-cmm.979(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 43 64 176 70 25 235 114 143 18 0 0 0 16 0 ...etc... filenameString: 'Morphic-cmm.979(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-cmm.979') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-cmm.979) filenameString: 'Morphic-cmm.979(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 8:00:18 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.979) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.979.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-cmm.979') Arguments and temporary variables: aFileName: 'Morphic-cmm.979(kfr.908)' aProject: The Trunk diffName: 'Morphic-cmm.979(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-cmm.979) Receiver's instance variables: timestamp: 16 May 2015 8:00:18 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.979) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.979.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.979') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 8:01:15 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.979') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.979') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 8:01:15 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.979') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-cmm.979') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-cmm.978(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 44 72 176 70 25 235 114 143 18 0 0 0 16 0 ...etc... filenameString: 'Morphic-cmm.978(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-cmm.978') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-cmm.978) filenameString: 'Morphic-cmm.978(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 9:00:20 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.978) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.978.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-cmm.978') Arguments and temporary variables: aFileName: 'Morphic-cmm.978(kfr.908)' aProject: The Trunk diffName: 'Morphic-cmm.978(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-cmm.978) Receiver's instance variables: timestamp: 16 May 2015 9:00:20 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.978) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.978.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.978') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 9:01:16 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.978') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.978') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 9:01:16 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.978') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-cmm.978') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read >forceNewFileNamed: Receiver: MultiByteFileStream Arguments and temporary variables: fileName: '/home/squeaksource/sso2/ss/trunk/Morphic-cmm.977(kfr.908).mcd' dir: nil localName: nil fullName: '/home/squeaksource/sso2/ss/trunk/Morphic-cmm.977(kfr.908).mcd' f: nil Receiver's instance variables: superclass: StandardFileStream methodDict: a MethodDictionary(#accepts:->(MultiByteFileStream>>#accepts: "a Co...etc... format: 156 instanceVariables: #('converter' 'lineEndConvention' 'wantsLineEndConversion') organization: ('accessing' ascii binary converter converter: fileInEncodingName...etc... subclasses: nil name: #MultiByteFileStream classPool: a Dictionary(#Cr->Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-cmm.977(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 43 80 176 70 25 235 114 143 18 0 0 0 16 0 ...etc... filenameString: 'Morphic-cmm.977(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-cmm.977') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-cmm.977) filenameString: 'Morphic-cmm.977(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 10:00:22 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.977) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.977.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-cmm.977') Arguments and temporary variables: aFileName: 'Morphic-cmm.977(kfr.908)' aProject: The Trunk diffName: 'Morphic-cmm.977(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-cmm.977) Receiver's instance variables: timestamp: 16 May 2015 10:00:22 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.977) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.977.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.977') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 10:01:12 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.977') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.977') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 10:01:12 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.977') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-cmm.977') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-cmm.976(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 42 88 176 70 25 235 114 143 18 0 0 0 16 0 ...etc... filenameString: 'Morphic-cmm.976(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-cmm.976') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-cmm.976) filenameString: 'Morphic-cmm.976(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 11:00:18 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.976) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.976.mcz...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-cmm.976') Arguments and temporary variables: aFileName: 'Morphic-cmm.976(kfr.908)' aProject: The Trunk diffName: 'Morphic-cmm.976(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-cmm.976) Receiver's instance variables: timestamp: 16 May 2015 11:00:18 am author: Chris Muller versionInfo: a MCVersionInfo(Morphic-cmm.976) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-cmm.976.mcz...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.976') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 11:01:10 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.976') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-cmm.976') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 11:01:10 am stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-cmm.976') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-cmm.976') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-mt.975(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 42 96 176 70 25 235 114 143 18 0 0 0 16 0 ...etc... filenameString: 'Morphic-mt.975(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-mt.975') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.975) filenameString: 'Morphic-mt.975(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 12:00:22 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.975) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.975.mcz'...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-mt.975') Arguments and temporary variables: aFileName: 'Morphic-mt.975(kfr.908)' aProject: The Trunk diffName: 'Morphic-mt.975(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-mt.975) Receiver's instance variables: timestamp: 16 May 2015 12:00:22 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.975) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.975.mcz'...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.975') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 12:01:11 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.975') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.975') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 12:01:11 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.975') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-mt.975') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-mt.974(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 44 104 176 70 25 235 114 143 18 0 0 0 16 0...etc... filenameString: 'Morphic-mt.974(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-mt.974') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.974) filenameString: 'Morphic-mt.974(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:00:21 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.974) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.974.mcz'...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-mt.974') Arguments and temporary variables: aFileName: 'Morphic-mt.974(kfr.908)' aProject: The Trunk diffName: 'Morphic-mt.974(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-mt.974) Receiver's instance variables: timestamp: 16 May 2015 1:00:21 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.974) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.974.mcz'...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.974') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:01:14 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.974') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.974') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 1:01:14 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.974') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-mt.974') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-topa.973(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 48 112 176 70 25 235 114 143 18 0 0 0 16 0...etc... filenameString: 'Morphic-topa.973(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-topa.973') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-topa.973) filenameString: 'Morphic-topa.973(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:00:29 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-topa.973) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-topa.973.mc...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-topa.973') Arguments and temporary variables: aFileName: 'Morphic-topa.973(kfr.908)' aProject: The Trunk diffName: 'Morphic-topa.973(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-topa.973) Receiver's instance variables: timestamp: 16 May 2015 2:00:29 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-topa.973) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-topa.973.mc...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-topa.973') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:01:23 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-topa.973') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-topa.973') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 2:01:23 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-topa.973') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-topa.973') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-mt.972(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 48 120 176 70 25 235 114 143 18 0 0 0 16 0...etc... filenameString: 'Morphic-mt.972(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-mt.972') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.972) filenameString: 'Morphic-mt.972(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:00:21 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.972) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.972.mcz'...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-mt.972') Arguments and temporary variables: aFileName: 'Morphic-mt.972(kfr.908)' aProject: The Trunk diffName: 'Morphic-mt.972(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-mt.972) Receiver's instance variables: timestamp: 16 May 2015 3:00:21 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.972) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.972.mcz'...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.972') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:24 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.972') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.972') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 3:01:24 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.972') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-mt.972') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-mt.971(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 45 128 176 70 25 235 114 143 18 0 0 0 16 0...etc... filenameString: 'Morphic-mt.971(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-mt.971') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.971) filenameString: 'Morphic-mt.971(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:00:22 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.971) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.971.mcz'...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-mt.971') Arguments and temporary variables: aFileName: 'Morphic-mt.971(kfr.908)' aProject: The Trunk diffName: 'Morphic-mt.971(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-mt.971) Receiver's instance variables: timestamp: 16 May 2015 4:00:22 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.971) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.971.mcz'...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.971') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:01:19 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.971') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.971') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 4:01:19 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.971') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-mt.971') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read Character cr #CrLf->' ' #Lf->Character lf #LineEn...etc... sharedPools: nil environment: Smalltalk category: #'Multilingual-TextConversion' UnixFileDirectory(FileDirectory)>>forceNewFileNamed: Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' Arguments and temporary variables: localFileName: 'Morphic-mt.970(kfr.908).mcd' Receiver's instance variables: pathName: FilePath('/home/squeaksource/sso2/ss/trunk') SSFilesystem>>saveMcBytes:named:to: Receiver: a SSFilesystem Arguments and temporary variables: aByteArray: #[80 75 3 4 20 0 0 0 8 0 43 136 176 70 25 235 114 143 18 0 0 0 16 0...etc... filenameString: 'Morphic-mt.970(kfr.908).mcd' aProject: The Trunk directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' stream: nil Receiver's instance variables: a SSFilesystem SSVersion*(SSVersion)>>saveDiff:named:to: Receiver: SSVersion*('Morphic-mt.970') Arguments and temporary variables: aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.970) filenameString: 'Morphic-mt.970(kfr.908).mcd' aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:00:20 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.970) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.970.mcz'...etc... downloadStatistics: nil SSVersion*(SSVersion)>>ensureDiffyVersion:in: Receiver: SSVersion*('Morphic-mt.970') Arguments and temporary variables: aFileName: 'Morphic-mt.970(kfr.908)' aProject: The Trunk diffName: 'Morphic-mt.970(kfr.908).mcd' diffyVersion: a MCDiffyVersion(Morphic-mt.970) Receiver's instance variables: timestamp: 16 May 2015 5:00:20 pm author: Chris Muller versionInfo: a MCVersionInfo(Morphic-mt.970) dependencies: #() properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.970.mcz'...etc... downloadStatistics: nil [] in SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter BlockClosure>>on:do: Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: handlerActive: false Receiver's instance variables: outerContext: SSDiffyTextWriter>>writeVersion:for: startpc: 119 numArgs: 0 SSDiffyTextWriter>>writeVersion:for: Receiver: a SSDiffyTextWriter Arguments and temporary variables: < Receiver's instance variables: stream: a WriteStream textWriter: a MCDiffyTextWriter [] in SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.970') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:01:15 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.970') sender: 'commits@source.squeak.org' BlockClosure>>on:do: Receiver: [closure] in SSEMailSubscription>>versionAdded:to: Arguments and temporary variables: exception: Error handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: handlerActive: true Receiver's instance variables: outerContext: SSEMailSubscription>>versionAdded:to: startpc: 111 numArgs: 0 SSEMailSubscription>>versionAdded:to: Receiver: a SSEMailSubscription Arguments and temporary variables: aVersion: SSVersion*('Morphic-mt.970') aProject: The Trunk Receiver's instance variables: timestamp: 16 May 2015 5:01:15 pm stream: a WriteStream project: The Trunk version: SSVersion*('Morphic-mt.970') sender: 'commits@source.squeak.org' [] in [] in SSProject*(SSProject)>>versionAdded: Receiver: The Trunk Arguments and temporary variables: aVersion: SSEMailSubscription each: SSVersion*('Morphic-mt.970') Receiver's instance variables: timestamp: 2 July 2009 4:00:59 pm id: 'trunk' title: 'The Trunk' description: 'You might want to read References: <5557238b.4326340a.22ef.ffff9cf5SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Drat -- emails got turned back on, probably due to a restart, I'll have to turn them off in the run script... On Sat, May 16, 2015 at 8:01 AM, wrote: > Chris Muller uploaded a new version of Morphic to project The Trunk: > http://source.squeak.org/trunk/Morphic-mt.974.mcz > > ==================== Summary ==================== > > Name: Morphic-mt.974 > Author: mt > Time: 8 May 2015, 4:18:52.877 pm > UUID: 6eeb73ef-2f37-4b4c-b686-f06aa396fff2 > Ancestors: Morphic-topa.973 > > Remove drop shadow when dragging dialog boxes. > > ==== ERROR === > > FileDoesNotExistException: '/home/squeaksource/sso2/ss/trunk/Morphic-mt.974(kfr.908).mcd' > > 16 May 2015 1:01:24.42 pm > > VM: unix - Smalltalk > Image: Squeak4.5 [latest update: #15015] > > SecurityManager state: > Restricted: false > FileAccess: true > SocketAccess: true > Working Dir /home/squeaksource/sso2 > Trusted Dir /home/squeaksource/sso2/secure > Untrusted Dir /home/squeaksource/sso2/My Squeak > > MultiByteFileStream class(StandardFileStream class)>>forceNewFileNamed: > Receiver: MultiByteFileStream > Arguments and temporary variables: > fileName: '/home/squeaksource/sso2/ss/trunk/Morphic-mt.974(kfr.908).mcd' > dir: nil > localName: nil > fullName: '/home/squeaksource/sso2/ss/trunk/Morphic-mt.974(kfr.908).mcd' > f: nil > Receiver's instance variables: > superclass: StandardFileStream > methodDict: a MethodDictionary(#accepts:->(MultiByteFileStream>>#accepts: "a Co...etc... > format: 156 > instanceVariables: #('converter' 'lineEndConvention' 'wantsLineEndConversion') > organization: ('accessing' ascii binary converter converter: fileInEncodingName...etc... > subclasses: nil > name: #MultiByteFileStream > classPool: a Dictionary(#Cr->Character cr #CrLf->' > ' #Lf->Character lf #LineEn...etc... > sharedPools: nil > environment: Smalltalk > category: #'Multilingual-TextConversion' > > UnixFileDirectory(FileDirectory)>>forceNewFileNamed: > Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' > Arguments and temporary variables: > localFileName: 'Morphic-mt.974(kfr.908).mcd' > Receiver's instance variables: > pathName: FilePath('/home/squeaksource/sso2/ss/trunk') > > SSFilesystem>>saveMcBytes:named:to: > Receiver: a SSFilesystem > Arguments and temporary variables: > aByteArray: #[80 75 3 4 20 0 0 0 8 0 44 104 176 70 25 235 114 143 18 0 0 0 16 0...etc... > filenameString: 'Morphic-mt.974(kfr.908).mcd' > aProject: The Trunk > directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' > stream: nil > Receiver's instance variables: > a SSFilesystem > > SSVersion*(SSVersion)>>saveDiff:named:to: > Receiver: SSVersion*('Morphic-mt.974') > Arguments and temporary variables: > aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.974) > filenameString: 'Morphic-mt.974(kfr.908).mcd' > aProject: The Trunk > Receiver's instance variables: > timestamp: 16 May 2015 1:00:21 pm > author: Chris Muller > versionInfo: a MCVersionInfo(Morphic-mt.974) > dependencies: #() > properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.974.mcz'...etc... > downloadStatistics: nil > > SSVersion*(SSVersion)>>ensureDiffyVersion:in: > Receiver: SSVersion*('Morphic-mt.974') > Arguments and temporary variables: > aFileName: 'Morphic-mt.974(kfr.908)' > aProject: The Trunk > diffName: 'Morphic-mt.974(kfr.908).mcd' > diffyVersion: a MCDiffyVersion(Morphic-mt.974) > Receiver's instance variables: > timestamp: 16 May 2015 1:00:21 pm > author: Chris Muller > versionInfo: a MCVersionInfo(Morphic-mt.974) > dependencies: #() > properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.974.mcz'...etc... > downloadStatistics: nil > > [] in SSDiffyTextWriter>>writeVersion:for: > Receiver: a SSDiffyTextWriter > Arguments and temporary variables: > < > Receiver's instance variables: > stream: a WriteStream > textWriter: a MCDiffyTextWriter > > BlockClosure>>on:do: > Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: > Arguments and temporary variables: > exception: Error > handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: > handlerActive: false > Receiver's instance variables: > outerContext: SSDiffyTextWriter>>writeVersion:for: > startpc: 119 > numArgs: 0 > > SSDiffyTextWriter>>writeVersion:for: > Receiver: a SSDiffyTextWriter > Arguments and temporary variables: > < > Receiver's instance variables: > stream: a WriteStream > textWriter: a MCDiffyTextWriter > > [] in SSEMailSubscription>>versionAdded:to: > Receiver: a SSEMailSubscription > Arguments and temporary variables: > aVersion: SSVersion*('Morphic-mt.974') > aProject: The Trunk > Receiver's instance variables: > timestamp: 16 May 2015 1:01:14 pm > stream: a WriteStream > project: The Trunk > version: SSVersion*('Morphic-mt.974') > sender: 'commits@source.squeak.org' > > BlockClosure>>on:do: > Receiver: [closure] in SSEMailSubscription>>versionAdded:to: > Arguments and temporary variables: > exception: Error > handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: > handlerActive: true > Receiver's instance variables: > outerContext: SSEMailSubscription>>versionAdded:to: > startpc: 111 > numArgs: 0 > > SSEMailSubscription>>versionAdded:to: > Receiver: a SSEMailSubscription > Arguments and temporary variables: > aVersion: SSVersion*('Morphic-mt.974') > aProject: The Trunk > Receiver's instance variables: > timestamp: 16 May 2015 1:01:14 pm > stream: a WriteStream > project: The Trunk > version: SSVersion*('Morphic-mt.974') > sender: 'commits@source.squeak.org' > > [] in [] in SSProject*(SSProject)>>versionAdded: > Receiver: The Trunk > Arguments and temporary variables: > aVersion: SSEMailSubscription > each: SSVersion*('Morphic-mt.974') > Receiver's instance variables: > timestamp: 2 July 2009 4:00:59 pm > id: 'trunk' > title: 'The Trunk' > description: 'You might want to read > format: 156 >> instanceVariables: #('converter' 'lineEndConvention' 'wantsLineEndConversion') >> organization: ('accessing' ascii binary converter converter: fileInEncodingName...etc... >> subclasses: nil >> name: #MultiByteFileStream >> classPool: a Dictionary(#Cr->Character cr #CrLf->' >> ' #Lf->Character lf #LineEn...etc... >> sharedPools: nil >> environment: Smalltalk >> category: #'Multilingual-TextConversion' >> >> UnixFileDirectory(FileDirectory)>>forceNewFileNamed: >> Receiver: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' >> Arguments and temporary variables: >> localFileName: 'Morphic-mt.974(kfr.908).mcd' >> Receiver's instance variables: >> pathName: FilePath('/home/squeaksource/sso2/ss/trunk') >> >> SSFilesystem>>saveMcBytes:named:to: >> Receiver: a SSFilesystem >> Arguments and temporary variables: >> aByteArray: #[80 75 3 4 20 0 0 0 8 0 44 104 176 70 25 235 114 143 18 0 0 0 16 0...etc... >> filenameString: 'Morphic-mt.974(kfr.908).mcd' >> aProject: The Trunk >> directory: UnixFileDirectory on '/home/squeaksource/sso2/ss/trunk' >> stream: nil >> Receiver's instance variables: >> a SSFilesystem >> >> SSVersion*(SSVersion)>>saveDiff:named:to: >> Receiver: SSVersion*('Morphic-mt.974') >> Arguments and temporary variables: >> aMCDiffyVersion: a MCDiffyVersion(Morphic-mt.974) >> filenameString: 'Morphic-mt.974(kfr.908).mcd' >> aProject: The Trunk >> Receiver's instance variables: >> timestamp: 16 May 2015 1:00:21 pm >> author: Chris Muller >> versionInfo: a MCVersionInfo(Morphic-mt.974) >> dependencies: #() >> properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.974.mcz'...etc... >> downloadStatistics: nil >> >> SSVersion*(SSVersion)>>ensureDiffyVersion:in: >> Receiver: SSVersion*('Morphic-mt.974') >> Arguments and temporary variables: >> aFileName: 'Morphic-mt.974(kfr.908)' >> aProject: The Trunk >> diffName: 'Morphic-mt.974(kfr.908).mcd' >> diffyVersion: a MCDiffyVersion(Morphic-mt.974) >> Receiver's instance variables: >> timestamp: 16 May 2015 1:00:21 pm >> author: Chris Muller >> versionInfo: a MCVersionInfo(Morphic-mt.974) >> dependencies: #() >> properties: a Dictionary(#diffs->a Dictionary() #fileName->'Morphic-mt.974.mcz'...etc... >> downloadStatistics: nil >> >> [] in SSDiffyTextWriter>>writeVersion:for: >> Receiver: a SSDiffyTextWriter >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> stream: a WriteStream >> textWriter: a MCDiffyTextWriter >> >> BlockClosure>>on:do: >> Receiver: [closure] in SSDiffyTextWriter>>writeVersion:for: >> Arguments and temporary variables: >> exception: Error >> handlerAction: [closure] in SSDiffyTextWriter>>writeVersion:for: >> handlerActive: false >> Receiver's instance variables: >> outerContext: SSDiffyTextWriter>>writeVersion:for: >> startpc: 119 >> numArgs: 0 >> >> SSDiffyTextWriter>>writeVersion:for: >> Receiver: a SSDiffyTextWriter >> Arguments and temporary variables: >> < >> Receiver's instance variables: >> stream: a WriteStream >> textWriter: a MCDiffyTextWriter >> >> [] in SSEMailSubscription>>versionAdded:to: >> Receiver: a SSEMailSubscription >> Arguments and temporary variables: >> aVersion: SSVersion*('Morphic-mt.974') >> aProject: The Trunk >> Receiver's instance variables: >> timestamp: 16 May 2015 1:01:14 pm >> stream: a WriteStream >> project: The Trunk >> version: SSVersion*('Morphic-mt.974') >> sender: 'commits@source.squeak.org' >> >> BlockClosure>>on:do: >> Receiver: [closure] in SSEMailSubscription>>versionAdded:to: >> Arguments and temporary variables: >> exception: Error >> handlerAction: [closure] in SSEMailSubscription>>versionAdded:to: >> handlerActive: true >> Receiver's instance variables: >> outerContext: SSEMailSubscription>>versionAdded:to: >> startpc: 111 >> numArgs: 0 >> >> SSEMailSubscription>>versionAdded:to: >> Receiver: a SSEMailSubscription >> Arguments and temporary variables: >> aVersion: SSVersion*('Morphic-mt.974') >> aProject: The Trunk >> Receiver's instance variables: >> timestamp: 16 May 2015 1:01:14 pm >> stream: a WriteStream >> project: The Trunk >> version: SSVersion*('Morphic-mt.974') >> sender: 'commits@source.squeak.org' >> >> [] in [] in SSProject*(SSProject)>>versionAdded: >> Receiver: The Trunk >> Arguments and temporary variables: >> aVersion: SSEMailSubscription >> each: SSVersion*('Morphic-mt.974') >> Receiver's instance variables: >> timestamp: 2 July 2009 4:00:59 pm >> id: 'trunk' >> title: 'The Trunk' >> description: 'You might want to read >changeKeys (in category 'as yet unclassified') ----- changeKeys upDownCodes := Dictionary new. + changeKeysState := #(up down left right in out). - changeKeysState := #(up down in out). self changed.! Item was changed: ----- Method: ZoomAndScrollControllerMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" | displayer dataMorph | super initialize. "" hasFocus := true. currentKeyDown := Set new. upDownCodes := Dictionary new. + upDownCodes at: 31 put: #up; "arrow keys" + at: 30 put: #down; + at: 29 put: #left; + at: 28 put: #right; + at: 88 put:#in; "x" + at: 90 put:#out. "y" + - upDownCodes at: 126 put: #up; - at: 125 put: #down; - at: 123 put: #out; - at: 124 put: #in. - "arrow keys on the mac" self extent: 40 @ 40; vResizing: #rigid; hResizing: #spaceFill; setBalloonText: 'Drag in here to zoom, tilt and pan the page above'. dataMorph := AlignmentMorph newColumn. dataMorph color: Color yellow; hResizing: #shrinkWrap; vResizing: #shrinkWrap. dataMorph on: #mouseDown send: #grabCameraPositionEvent:morph: to: self. displayer := UpdatingStringMorph new getSelector: #cameraPointRounded; target: self; growable: true; putSelector: nil. dataMorph addMorph: displayer lock. displayer := UpdatingStringMorph new getSelector: #cameraScale; target: self; growable: true; floatPrecision: 0.001; putSelector: nil. dataMorph addMorph: displayer lock. self addMorph: dataMorph! Item was changed: ----- Method: ZoomAndScrollControllerMorph>>step (in category 'stepping and presenter') ----- step + | delta halfDW shift | + shift := false. - | delta halfDW | - (self valueOfProperty: #currentCameraVersion ifAbsent: [0]) = self currentCameraVersion ifFalse: [ self patchOldVersion1. self setProperty: #currentCameraVersion toValue: self currentCameraVersion. ]. super step. self doProgrammedMoves. + (currentKeyDown ifNil: [#()]) do: [ :each | | action | + action := upDownCodes at: each ifAbsent: [shift := true]. - (currentKeyDown ifNil: [#()]) do: [ :each | | action | - action := upDownCodes at: each ifAbsent: [#fugeddaboutit]. action == #in ifTrue: [ target scaleImageBy: -10. ]. action == #out ifTrue: [ target scaleImageBy: 10. ]. action == #up ifTrue: [ + target panImageBy: 0@ -20. - target tiltImageBy: -20. ]. action == #down ifTrue: [ + target panImageBy: 0@20. - target tiltImageBy: 20. ]. + action == #left ifTrue: [ + target panImageBy: -20@0. + ]. + action == #right ifTrue: [ + target panImageBy: 20@0. + ]. ]. mouseMovePoint ifNil: [^self]. mouseDownPoint ifNil: [^self]. target ifNil: [^self]. halfDW := self deadZoneWidth // 2. + halfDW := self deadZoneWidth // 2. delta := mouseMovePoint - mouseDownPoint. delta x abs <= halfDW ifTrue: [delta := 0@delta y]. delta y abs <= halfDW ifTrue: [delta := delta x@0]. + shift ifTrue:[^target scaleImageBy: delta x]. + target panImageBy: delta x @ delta y - - target panImageBy: delta x. ! Item was changed: ----- Method: ZoomAndScrollMorph>>panImageBy: (in category 'as yet unclassified') ----- panImageBy: pixels + self changeOffsetBy: (pixels x* self getTiltFactor * 0.1) @ (pixels y* self getTiltFactor * 0.1) - self changeOffsetBy: (pixels * self getTiltFactor * 0.1) @ 0. "steps := (pixels abs / 6) exp rounded * pixels sign." "==Alan's preferred factors pan = 0.0425531914893617 zoom = 0.099290780141844 ===" ! Item was removed: - ----- Method: ZoomAndScrollMorph>>tiltImageBy: (in category 'as yet unclassified') ----- - tiltImageBy: pixels - - self changeOffsetBy: 0 @ (pixels * self getTiltFactor * 0.1) - - " steps := (pixels abs / 6) exp rounded * pixels sign. - " - "==Alan's preferred factors - pan = 0.0425531914893617 - zoom = 0.099290780141844 - ===" - ! From commits at source.squeak.org Sun May 17 21:44:25 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 17 21:44:26 2015 Subject: [squeak-dev] The Inbox: MorphicExtras-kfr.164.mcz Message-ID: A new version of MorphicExtras was added to project The Inbox: http://source.squeak.org/inbox/MorphicExtras-kfr.164.mcz ==================== Summary ==================== Name: MorphicExtras-kfr.164 Author: kfr Time: 17 May 2015, 11:38:22.475 pm UUID: ce706845-ed00-3b46-ab92-8169dc372543 Ancestors: MorphicExtras-nice.163 Revive StoryboardBookMorph =============== Diff against MorphicExtras-nice.163 =============== Item was changed: BookMorph subclass: #StoryboardBookMorph instanceVariableNames: 'alansSliders panAndTiltFactor zoomFactor zoomController' classVariableNames: '' poolDictionaries: '' category: 'MorphicExtras-Books'! + !StoryboardBookMorph commentStamp: 'kfr 5/17/2015 23:37' prior: 0! + A BookMorph variant whose pages are instances of ZoomAndScrollMorph. + I have a control area where the user may pan, tilt and zoom over the image shown in the page. - !StoryboardBookMorph commentStamp: '' prior: 0! - A BookMorph variant whose pages are instances of ZoomAndScrollMorph. I have a control area where the user may pan, tilt and zoom over the image shown in the page. + StoryboardBookMorph new openInWorld + + Drop an picture at the book. + + Mouse + - drag up and down to tilt - - drag up and down to zoom in and out - drag left and right to pan + - shift-drag up and down to zoom in and out + + Keyboard + Arrow keys pan and tilts the image + X and Z zoom in and out + + From top left in control panel you pull out stills from diffrent zoom, tilt and pan posititons. + Drop these after eachother to make an animation script. + The numbers between the stills are playback speed, that can be edited. + Save script from the scripts halo menu. + + Playback script from controll panels halo menu. + + ! - - shift-drag up and down to tilt.! Item was changed: ----- Method: StoryboardBookMorph>>initialize (in category 'initialization') ----- initialize + newPagePrototype := ZoomAndScrollMorph new extent: 300@300. - newPagePrototype := ZoomAndScrollMorph new extent: Display extent // 3. zoomController := ZoomAndScrollControllerMorph new + setBalloonText: 'Drag in here to zoom, tilt and pan the page above'; + extent: 246@147. - setBalloonText: 'Drag in here to zoom, tilt and pan the page above'. super initialize. + zoomController openInWorld. + + "tool := RectangleMorph new extent: 250@170; layoutPolicy: TableLayout new. + tool addMorph: zoomController. - self addMorphBack: zoomController. - alansSliders := { {#changeTiltFactor: . #getTiltFactor . 'Pan and tilt sensitivity'}. {#changeZoomFactor: . #getZoomFactor . 'Zoom sensitivity'}. } collect: [ :sData | { SimpleSliderMorph new extent: 150@10; color: Color orange; sliderColor: Color gray; target: self; actionSelector: sData first; setBalloonText: sData third; adjustToValue: (self perform: sData second). sData second } ]. + alansSliders do: [ :each | tool addMorphBack: each first]. + tool openInWorld" - alansSliders do: [ :each | self addMorphBack: each first] ! Item was changed: ----- Method: ZoomAndScrollControllerMorph>>changeKeys (in category 'as yet unclassified') ----- changeKeys upDownCodes := Dictionary new. + changeKeysState := #(up down left right in out). - changeKeysState := #(up down in out). self changed.! Item was changed: ----- Method: ZoomAndScrollControllerMorph>>initialize (in category 'initialization') ----- initialize "initialize the state of the receiver" | displayer dataMorph | super initialize. "" hasFocus := true. currentKeyDown := Set new. upDownCodes := Dictionary new. + upDownCodes at: 31 put: #up; "arrow keys" + at: 30 put: #down; + at: 29 put: #left; + at: 28 put: #right; + at: 88 put:#in; "x" + at: 90 put:#out. "y" + - upDownCodes at: 126 put: #up; - at: 125 put: #down; - at: 123 put: #out; - at: 124 put: #in. - "arrow keys on the mac" self extent: 40 @ 40; vResizing: #rigid; hResizing: #spaceFill; setBalloonText: 'Drag in here to zoom, tilt and pan the page above'. dataMorph := AlignmentMorph newColumn. dataMorph color: Color yellow; hResizing: #shrinkWrap; vResizing: #shrinkWrap. dataMorph on: #mouseDown send: #grabCameraPositionEvent:morph: to: self. displayer := UpdatingStringMorph new getSelector: #cameraPointRounded; target: self; growable: true; putSelector: nil. dataMorph addMorph: displayer lock. displayer := UpdatingStringMorph new getSelector: #cameraScale; target: self; growable: true; floatPrecision: 0.001; putSelector: nil. dataMorph addMorph: displayer lock. self addMorph: dataMorph! Item was changed: ----- Method: ZoomAndScrollControllerMorph>>step (in category 'stepping and presenter') ----- step + | delta halfDW shift | + shift := false. - | delta halfDW | - (self valueOfProperty: #currentCameraVersion ifAbsent: [0]) = self currentCameraVersion ifFalse: [ self patchOldVersion1. self setProperty: #currentCameraVersion toValue: self currentCameraVersion. ]. super step. self doProgrammedMoves. + (currentKeyDown ifNil: [#()]) do: [ :each | | action | + action := upDownCodes at: each ifAbsent: [shift := true]. - (currentKeyDown ifNil: [#()]) do: [ :each | | action | - action := upDownCodes at: each ifAbsent: [#fugeddaboutit]. action == #in ifTrue: [ target scaleImageBy: -10. ]. action == #out ifTrue: [ target scaleImageBy: 10. ]. action == #up ifTrue: [ + target tiltImageBy: 0@ -20. - target tiltImageBy: -20. ]. action == #down ifTrue: [ + target tiltImageBy: 0@20. - target tiltImageBy: 20. ]. + action == #left ifTrue: [ + target tiltImageBy: -20@0. + ]. + action == #right ifTrue: [ + target tiltImageBy: 20@0. + ]. ]. mouseMovePoint ifNil: [^self]. mouseDownPoint ifNil: [^self]. target ifNil: [^self]. halfDW := self deadZoneWidth // 2. + halfDW := self deadZoneWidth // 2. delta := mouseMovePoint - mouseDownPoint. delta x abs <= halfDW ifTrue: [delta := 0@delta y]. delta y abs <= halfDW ifTrue: [delta := delta x@0]. + shift ifTrue:[ target scaleImageBy: delta x]. + target panImageBy: delta x @ delta y - - target panImageBy: delta x. ! Item was changed: ----- Method: ZoomAndScrollMorph>>panImageBy: (in category 'as yet unclassified') ----- panImageBy: pixels + self changeOffsetBy: (pixels x* self getTiltFactor * 0.1) @ (pixels y* self getTiltFactor * 0.1) - self changeOffsetBy: (pixels * self getTiltFactor * 0.1) @ 0. "steps := (pixels abs / 6) exp rounded * pixels sign." "==Alan's preferred factors pan = 0.0425531914893617 zoom = 0.099290780141844 ===" ! Item was changed: ----- Method: ZoomAndScrollMorph>>tiltImageBy: (in category 'as yet unclassified') ----- tiltImageBy: pixels + self changeOffsetBy: (pixels x * self getTiltFactor * 0.1) @ (pixels y * self getTiltFactor * 0.1) - self changeOffsetBy: 0 @ (pixels * self getTiltFactor * 0.1) " steps := (pixels abs / 6) exp rounded * pixels sign. " "==Alan's preferred factors pan = 0.0425531914893617 zoom = 0.099290780141844 ===" ! From eliot.miranda at gmail.com Mon May 18 03:23:02 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon May 18 03:23:08 2015 Subject: [squeak-dev] New Cog VMs available Message-ID: ...at http://www.mirandabanda.org/files/Cog/VM/VM.r3349. I hope that the Squeak VMs here-in are final Spur 5.0 and Squeak 4.6 VMs. The last known serious bug in Spur has been found and fixed with these VMs. Of course uch hubris is asking for it. I await the wrath of the gods. CogVM binaries as per VMMaker.oscog-eem.1313/r3349 General: Make the bounds check in primitiveObject:perform:... more restrictive and fix bugs in the commentary. Make stack pages a reasonable size. My math was wrong and the size was half as big as intended. Extend the fastPrimTrace scheme to trace stack overflow, prim failure and prim retry to help debug the phantom stack frame bug in Cog Spur. Fix old bug in ceMNUFromPICMNUMethod:receiver: that has been masked by cacheing of MNU method in MNU PIC entries. ceMNUFromPICMNUMethod:receiver: must set up lkupClass before calling handleMNU:... Spur: Fix ceActivateFailingPrimitiveMethod: to return properly after retrying a primitive after checkForAndFollowForwardedPrimitiveState. e.g. fixes | s | 1 to: 5 do: [:i| s := 'bar'. s becomeForward: 'bzzt' copy. 'foo' <= s] Fix bug in followForwardedFrameContents:stackPointer: so that arguments are actually followed. N.B. drives the above bug underground ;-). so that named constants (defines) are not elided. Make accessor depth calculation more accurate by not considering fetchInteger:ofObject: and arraySize: et al as object accessors. Make the read-before-written initializer safer, only initialzing simple types. Newspeak: Remove landmine left from restructing implicit receiver and outer sends as clean sends. Plugins: Regenerated because of changes in accessorDepth calculation, constant elimination, and read-before-use initialization. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150517/c5098d87/attachment.htm From eliot.miranda at gmail.com Mon May 18 04:28:23 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Mon May 18 04:28:28 2015 Subject: [squeak-dev] Re: New Cog VMs available In-Reply-To: References: Message-ID: and the gods, right on time, have smitten me down. The Slang changes have broken the VM, so I've taken the VMs down. On Sun, May 17, 2015 at 8:23 PM, Eliot Miranda wrote: > ...at http://www.mirandabanda.org/files/Cog/VM/VM.r3349. > > I hope that the Squeak VMs here-in are final Spur 5.0 and Squeak 4.6 VMs. > The last known serious bug in Spur has been found and fixed with these > VMs. Of course uch hubris is asking for it. I await the wrath of the gods. > > CogVM binaries as per VMMaker.oscog-eem.1313/r3349 > > General: > Make the bounds check in primitiveObject:perform:... > more restrictive and fix bugs in the commentary. > > Make stack pages a reasonable size. My math was > wrong and the size was half as big as intended. > > Extend the fastPrimTrace scheme to trace stack overflow, prim failure and > prim > retry to help debug the phantom stack frame bug in Cog Spur. > > Fix old bug in ceMNUFromPICMNUMethod:receiver: that has been masked by > cacheing of MNU method in MNU PIC entries. ceMNUFromPICMNUMethod:receiver: > must set up lkupClass before calling handleMNU:... > > Spur: > Fix ceActivateFailingPrimitiveMethod: to return properly after retrying > a primitive after checkForAndFollowForwardedPrimitiveState. e.g. fixes > | s | 1 to: 5 do: [:i| s := 'bar'. s becomeForward: 'bzzt' copy. 'foo' > <= s] > > Fix bug in followForwardedFrameContents:stackPointer: so that arguments are > actually followed. N.B. drives the above bug underground ;-). > so that named constants (defines) are not elided. > > Make accessor depth calculation more accurate by not considering > fetchInteger:ofObject: and arraySize: et al as object accessors. > > Make the read-before-written initializer safer, only initialzing simple > types. > > Newspeak: > Remove landmine left from restructing implicit receiver and outer sends as > clean sends. > > Plugins: > Regenerated because of changes in accessorDepth calculation, > constant elimination, and read-before-use initialization. > -- > best, > Eliot > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150517/a65154d8/attachment.htm From commits at source.squeak.org Mon May 18 08:16:59 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 18 08:17:03 2015 Subject: [squeak-dev] The Trunk: SystemReporter-mt.24.mcz Message-ID: Marcel Taeumel uploaded a new version of SystemReporter to project The Trunk: http://source.squeak.org/trunk/SystemReporter-mt.24.mcz ==================== Summary ==================== Name: SystemReporter-mt.24 Author: mt Time: 18 May 2015, 10:16:53.323 am UUID: 8a99a2df-13ea-6149-bcad-cb460f6c8e6b Ancestors: SystemReporter-dtl.23 Fixed confirm-actions for all longer lasting operations in the system reporter: space analysis, tiny benchmarks, test runner. Support 'cancel' for all of them. =============== Diff against SystemReporter-dtl.23 =============== Item was changed: ----- Method: SystemReporter>>reportSpaceAnalysis: (in category 'reporting') ----- reportSpaceAnalysis: aStream spaceAnalysisResult ifNil: [ + (UIManager default + confirm: 'Running the space analysis\might take a few seconds.' withCRs translated + title: 'Continue?' translated) + ifFalse: [ + categoriesSelected remove: #'Space Analysis'. + ^ self changed: #categorySelected ]. + - UIManager inform: 'Running the Space Analysis\will take a few seconds' withCRs. spaceAnalysisResult := String streamContents: [ :stream | SpaceTally new printSpaceAnalysis: 1 onStream: stream ] ]. self header: 'Space Analysis' on: aStream. aStream nextPutAll: spaceAnalysisResult; cr! Item was changed: ----- Method: SystemReporter>>reportTestRunner: (in category 'reporting') ----- reportTestRunner: aStream + + testRunner ifNil: [ + (UIManager default + confirm: 'Running all tests might\take a some minutes.' withCRs translated + title: 'Continue?') + ifTrue: [ testRunner := TestRunner new runAll ] + ifFalse: + [ categoriesSelected remove: #SUnit. + ^ self changed: #categorySelected ] ]. - testRunner ifNil: - [ | runAllTests | - runAllTests := UIManager confirm: 'Running all Tests\will take long time' withCRs. - runAllTests - ifTrue: [ testRunner := TestRunner new runAll ] - ifFalse: - [ categoriesSelected remove: #SUnit. - ^ self changed: #categorySelected ] ]. self header: 'SUnit Results' on: aStream. aStream nextPutAll: testRunner statusText ; cr ; cr. self header: 'Failed Tests' on: aStream. testRunner failedList do: [ : each | self printDebugExpressionFor: each on: aStream. aStream cr ]. aStream cr. self header: 'Errors' on: aStream. testRunner errorList do: [ : each | self printDebugExpressionFor: each on: aStream. aStream cr ]! Item was changed: ----- Method: SystemReporter>>reportTinyBenchmarks: (in category 'reporting') ----- reportTinyBenchmarks: aStream tinyBenchmarksResult ifNil: [ + (UIManager default + confirm: 'Running all benchmarks\might take a few seconds.' withCRs translated + title: 'Continue?' translated) + ifFalse: [ + categoriesSelected remove: #'Tiny Benchmarks'. + ^ self changed: #categorySelected ]. + Cursor wait showWhile: [tinyBenchmarksResult := 0 tinyBenchmarks]]. - UIManager inform: 'Running the Benchmarks\will take a few seconds' withCRs. - tinyBenchmarksResult := 0 tinyBenchmarks]. self header: 'Tiny Benchmarks' on: aStream. aStream nextPutAll: tinyBenchmarksResult; cr! From Marcel.Taeumel at hpi.de Mon May 18 08:09:50 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Mon May 18 08:27:02 2015 Subject: [squeak-dev] Re: The Trunk: SystemReporter-mt.24.mcz In-Reply-To: References: Message-ID: <1431936590647-4826995.post@n4.nabble.com> As for the current feature freeze: I got several complaints about triggering those tings in the system reporter by accident. So I regarded those things as kind of urgent. Please forgive my hasty response resp. commit. ;-) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-SystemReporter-mt-24-mcz-tp4826991p4826995.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Mon May 18 17:09:06 2015 From: karlramberg at gmail.com (karl ramberg) Date: Mon May 18 17:09:11 2015 Subject: [squeak-dev] [BUG] ObjectExplorer menu Message-ID: ObjectExplorer will fail to open a yellow button menu if you explore values that change while you are exploring them. The method updateInspectorSelection uses assert: to check if objects are the same as in a inspector, which they are not because they have changed in the background. I think this should be fixed before we release. ObjectExplorer>>updateInspectorForSelection "Reuse the inspector for some callbacks." self inspector inspect: (self parentObject ifNil: [self object]). self parentObject ifNil: [self inspector toggleIndex: 1. "self"] ifNotNil: [ self inspector toggleIndex: (self inspector fieldList indexOf: self currentSelection key)]. self assert: self inspector selection == self object. Karl -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150518/41734088/attachment.htm From commits at source.squeak.org Mon May 18 21:55:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Mon May 18 21:55:09 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150518215507.29130.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008700.html Name: SystemReporter-mt.24 Ancestors: SystemReporter-dtl.23 Fixed confirm-actions for all longer lasting operations in the system reporter: space analysis, tiny benchmarks, test runner. Support 'cancel' for all of them. ============================================= From rpboland at gmail.com Tue May 19 00:47:55 2015 From: rpboland at gmail.com (Ralph Boland) Date: Tue May 19 00:47:57 2015 Subject: [squeak-dev] which squeak sources/image/changes file should I use for Debian/Jessie Message-ID: I just downloaded and installed (via apt-get install) squeak-vm on my computer upon which I am running Debian/Jessie i386. I would like to know which sources file, image file and changes file I should download to match this image. I am looking for a stable version of squeak 4.5. Note that apt-get installed squeak-vm 1:4.10.2.2614-1.1+b1 which I assume to be compatible with squeak 4.5 Once this is installed I will be migrating my Squeak code from 3.11 to 4.5. Is there any gotchas that I should be aware of for this migration? Thanks Ralph Boland From commits at source.squeak.org Tue May 19 02:01:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 19 02:01:29 2015 Subject: [squeak-dev] The Trunk: Monticello-cmm.616.mcz Message-ID: Chris Muller uploaded a new version of Monticello to project The Trunk: http://source.squeak.org/trunk/Monticello-cmm.616.mcz ==================== Summary ==================== Name: Monticello-cmm.616 Author: cmm Time: 18 May 2015, 9:00:52.601 pm UUID: 2421b210-91a1-420a-bf0c-1f665533c904 Ancestors: Monticello-mt.615 - Fix potential security hole with clearPasswords and clearPasswordsAndUsers -- renamed them to #clearCredentials so we don't have my initials in the repositories of this release. - Clarify message about adding historical repository. =============== Diff against Monticello-mt.615 =============== Item was changed: ----- Method: MCHttpRepository class>>cleanUp: (in category 'class initialization') ----- cleanUp: aggressive super cleanUp: aggressive. + aggressive ifTrue: [ self clearCredentials ]! - aggressive ifTrue: [ self clearPasswords ]! Item was added: + ----- Method: MCHttpRepository class>>clearCredentials (in category 'class initialization') ----- + clearCredentials + self allSubInstancesDo: [ : each | each clearCredentials ]! Item was removed: - ----- Method: MCHttpRepository class>>clearPasswords (in category 'class initialization') ----- - clearPasswords - self allSubInstancesDo: [:ea | ea password: '']. - ! Item was removed: - ----- Method: MCHttpRepository class>>clearPasswordsAndUsers (in category 'class initialization') ----- - clearPasswordsAndUsers - self allSubInstancesDo: [:ea | ea user: ''; password: '']. - ! Item was added: + ----- Method: MCHttpRepository>>clearCredentials (in category 'accessing') ----- + clearCredentials + user atAllPut: $x. + password atAllPut: $x. + user := password := String empty! Item was changed: ----- Method: MCWorkingCopyBrowser class>>mcModelFor: (in category 'hooks') ----- mcModelFor: aClassOrMethodReference ^ aClassOrMethodReference mcModel ifNil: + [ | pkgName rep | (UIManager confirm: 'Okay to add historical repository ' , (rep := MCHttpRepository trunkBackup) description , ' to ' , (pkgName := aClassOrMethodReference packageInfo packageName) , '?') ifTrue: + [ (MCWorkingCopy forPackageNamed: pkgName) repositoryGroup addRepository: rep. - [ | pkgName | (UIManager confirm: 'Okay to add historical repository to ' , (pkgName := aClassOrMethodReference packageInfo packageName) , '?') ifTrue: - [ (MCWorkingCopy forPackageNamed: pkgName) repositoryGroup addRepository: MCHttpRepository trunkBackup. aClassOrMethodReference mcModel ] ]! From lewis at mail.msen.com Tue May 19 03:08:53 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 19 03:08:56 2015 Subject: [squeak-dev] which squeak sources/image/changes file should I use for Debian/Jessie In-Reply-To: References: Message-ID: <20150519030853.GA43719@shell.msen.com> On Mon, May 18, 2015 at 06:47:55PM -0600, Ralph Boland wrote: > I just downloaded and installed (via apt-get install) squeak-vm on my > computer upon which > I am running Debian/Jessie i386. > > I would like to know which sources file, image file and changes file I > should download to > match this image. I am looking for a stable version of squeak 4.5. > > Note that apt-get installed squeak-vm 1:4.10.2.2614-1.1+b1 which I assume to be > compatible with squeak 4.5 > > Once this is installed I will be migrating my Squeak code from 3.11 to 4.5. > Is there any gotchas that I should be aware of for this migration? Hi Ralph, I would recommend getting your image and VM through the references on http://www.squeak.org/Downloads. In particular, please get your VM through one of those links, rather than relying on apt-get. The Debian package may work, but problems have been reported particularly for 64-bit systems. Given your objective to move from 3.11 to 4.5, the official 4.5 release is a good image to work with. Be aware that a new release is pending. This will be 4.6/5.0, with the 5.0 designation applied to a new object memory format (by Eliot Miranda) that will support better performance and new garbage collection strategies. But you can very easily move your application from 4.5 to the newest 4.6/5.0 once you have in running on 4.5. The Cog VMs (mirandabanda.org) will give you superior performance, and the traditional interpreter VMs (squeakvm.org)) will work well with both Squeak 4.5 and your current 3.11 images. Any of these VMs will serve you well, but please do get one through the links at http://www.squeak.org/Downloads. HTH, Dave From eliot.miranda at gmail.com Tue May 19 04:30:00 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Tue May 19 04:30:05 2015 Subject: [squeak-dev] New CogVMs available Message-ID: at http://www.mirandabanda.org/files/Cog/VM/VM.r3350/. CogVM binaries as per VMMaker.oscog-eem.1315/r3350 General: Make the bounds check in primitiveObject:perform:... more restrictive and fix bugs in the commentary. Make stack pages a reasonable size. My math was wrong and the size was half as big as intended. Extend the fastPrimTrace scheme to trace stack overflow, prim failure and prim retry to help debug the phantom stack frame bug in Cog Spur. Cogit: Fix old bug in ceMNUFromPICMNUMethod:receiver: that has been masked by cacheing of MNU method in MNU PIC entries. ceMNUFromPICMNUMethod:receiver: must set up lkupClass before calling handleMNU:... Revamp icache flushing in the Cogit for ARM. Move icache flush for generated methods/pics to the fillIn*Header: routines. Make sure the cache is flushed in generateCaptureCStackPointers:. Flush the entire PIC when extending it. Fix ARM-only regression in StackToRegisterMappingCogit's PIC aborts when the SimpleStackBasedCogit was fixed. Make ARM rotated 8bit constants actually be correct(er) ie 16r4000001 (SmallInteger 16r2000000) work. Spur: Fix ceActivateFailingPrimitiveMethod: to return properly after retrying a primitive after checkForAndFollowForwardedPrimitiveState. e.g. fixes | s | 1 to: 5 do: [:i| s := 'bar'. s becomeForward: 'bzzt' copy. 'foo' <= s] Fix bug in followForwardedFrameContents:stackPointer: so that arguments are actually followed. N.B. drives the above bug underground ;-). so that named constants (defines) are not elided. Make accessor depth calculation more accurate by not considering fetchInteger:ofObject: and arraySize: et al as object accessors. Newspeak: Remove landmine left from restructing implicit receiver and outer sends as clean sends. Slang: Do a more thorough job of transforming complex to:[by:]do: loops so that the limit expression is only evaluated once, not on each iteration of the loop. Make the read-before-written initializer safer, only initialzing simple types. Plugins: Regenerated because of changes in accessorDepth calculation, constant elimination, and read-before-use initialization. -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150518/b71299fb/attachment.htm From tim at rowledge.org Tue May 19 05:19:26 2015 From: tim at rowledge.org (tim Rowledge) Date: Tue May 19 05:19:30 2015 Subject: [squeak-dev] which squeak sources/image/changes file should I use for Debian/Jessie In-Reply-To: <20150519030853.GA43719@shell.msen.com> References: <20150519030853.GA43719@shell.msen.com> Message-ID: On 18-05-2015, at 8:08 PM, David T. Lewis wrote: > I would recommend getting your image and VM through the references on > http://www.squeak.org/Downloads. In particular, please get your VM through > one of those links, rather than relying on apt-get. The Debian package may > work, but problems have been reported particularly for 64-bit systems. I?d second that; we used to use the debian repository for building the raspberry Pi vm to support Scratch but quickly realised it was never going to be adequate. They actually imposed patches on the code without ever having told anyone in squeak-land. Unnacceptable. It broke stuff! > > Given your objective to move from 3.11 to 4.5, the official 4.5 release > is a good image to work with. Be aware that a new release is pending. This > will be 4.6/5.0, with the 5.0 designation applied to a new object memory > format (by Eliot Miranda) that will support better performance and new > garbage collection strategies. But you can very easily move your application > from 4.5 to the newest 4.6/5.0 once you have in running on 4.5. Moving all the way from 3.x to 4,5 is not a trivial thing if your code include much morphic use. I had to move the Scratch (roughly 2.8 era) code forward and it was a massive effort. It might well be smarter to use your UI design and build a fresh ui code base rather than trying to patch things up as you go. I updated a fair bit of morph layout related pages on the swiki as a result of my ? travails. > > The Cog VMs (mirandabanda.org) will give you superior performance, and the > traditional interpreter VMs (squeakvm.org)) will work well with both Squeak > 4.5 and your current 3.11 images. Any of these VMs will serve you well, > but please do get one through the links at http://www.squeak.org/Downloads. You can almost certainly just use the all-in-one download if you are using an x86 linux machine. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful random insult:- Calls people to ask them their phone number. From Marcel.Taeumel at hpi.de Tue May 19 08:50:07 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 09:07:25 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object Message-ID: <1432025407002-4827263.post@n4.nabble.com> Hi, there! :) I just want to mention and explain, why (Object >> #inspect) now returns the tool window instead of the object as in 4.5. The Tools package adds several convenient methods to the base system: Object >> #explore Object >> #inspect Object >> #browse Behavior >> #browse All but #inspect returned the created tool. So I went for consistency. But in particular, those methods should return the tool because because otherwise the programmer has no simple means to access the created window/tool programmatically. Model and object are, however, always accessible (via #model or just #self). So if you got code like this: self someObjects add: myObject inspect. Please change it to: self someObjects add: myObject inspect; yourself. Or even better to: myObject inspect. self someObjects add: myObject. I think that it is good practice/style to use #yourself if you want to get the receiver back in a chain of calls: self myMorphs add: (MyMorph new color: Color yellow; yourself). Best, Marcel -- View this message in context: http://forum.world.st/Tools-Object-inspect-now-returns-the-tool-instead-of-the-object-tp4827263.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 19 08:53:39 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 09:10:57 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: References: Message-ID: <1432025619698-4827264.post@n4.nabble.com> This can be fixed by *not* reusing code of the Inspector class hierarchy. Should we copy? :) Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4827264.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Tue May 19 09:29:28 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 19 09:29:32 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: <1432025619698-4827264.post@n4.nabble.com> References: <1432025619698-4827264.post@n4.nabble.com> Message-ID: We must use another mechanism in explorer than in inspector. Items in the inspector list does not change or are updated continuously. The explorer list is (usually) frozen while items change in the background. Updating the list in explorer is quite slow so we don't want to do that continuously. Karl On Tue, May 19, 2015 at 10:53 AM, marcel.taeumel wrote: > This can be fixed by *not* reusing code of the Inspector class hierarchy. > Should we copy? :) > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4827264.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150519/6f55ef4f/attachment.htm From lewis at mail.msen.com Tue May 19 12:19:01 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 19 12:19:04 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: <1432025407002-4827263.post@n4.nabble.com> References: <1432025407002-4827263.post@n4.nabble.com> Message-ID: <20150519121901.GA42260@shell.msen.com> On Tue, May 19, 2015 at 01:50:07AM -0700, marcel.taeumel wrote: > Hi, there! :) > > I just want to mention and explain, why (Object >> #inspect) now returns the > tool window instead of the object as in 4.5. > > The Tools package adds several convenient methods to the base system: > > Object >> #explore > Object >> #inspect > Object >> #browse > Behavior >> #browse > > All but #inspect returned the created tool. So I went for consistency. But > in particular, those methods should return the tool because because > otherwise the programmer has no simple means to access the created > window/tool programmatically. Model and object are, however, always > accessible (via #model or just #self). Thanks for the explanation. I think that you made the right choice. Dave > > So if you got code like this: > > self someObjects add: myObject inspect. > > Please change it to: > > self someObjects add: myObject inspect; yourself. > > Or even better to: > > myObject inspect. > self someObjects add: myObject. > > I think that it is good practice/style to use #yourself if you want to get > the receiver back in a chain of calls: > > self myMorphs add: (MyMorph new color: Color yellow; yourself). > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/Tools-Object-inspect-now-returns-the-tool-instead-of-the-object-tp4827263.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 19 12:31:25 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 12:48:44 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: References: <1431317046736-4825620.post@n4.nabble.com> Message-ID: <1432038685392-4827343.post@n4.nabble.com> It seems that "Auto Enclose" is not honored correctly. It is disabled in my image but still seems to be enabled. :-( Try typing "()" then move the cursor between the parentheses and type the closing one again. You will not end up with to closing ones... Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-977-mcz-tp4825591p4827343.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From lecteur at zogotounga.net Tue May 19 13:20:05 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Tue May 19 13:20:04 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: <1432038685392-4827343.post@n4.nabble.com> References: <1431317046736-4825620.post@n4.nabble.com> <1432038685392-4827343.post@n4.nabble.com> Message-ID: <555B3885.8070006@zogotounga.net> > It seems that "Auto Enclose" is not honored correctly. It is disabled in my > image but still seems to be enabled. :-( > > Try typing "()" then move the cursor between the parentheses and type the > closing one again. You will not end up with to closing ones... Yes, I noticed that also, and it bothered me enough that I fixed it by modifying TextEditor>> #dispatchOnKeyboardEvent: as follow: ---------------------------------------------- dispatchOnKeyboardEvent: aKeyboardEvent "Carry out the action associated with this character, if any. Type-ahead is passed so some routines can flush or use it." | honorCommandKeys openers closers result typedChar | ((typedChar := aKeyboardEvent keyCharacter) == Character cr and: [ morph acceptOnCR ]) ifTrue: [ self closeTypeIn. ^ true ]. self clearParens. aKeyboardEvent keyValue = 13 ifTrue: [ aKeyboardEvent controlKeyPressed ifTrue: [ ^ self normalCharacter: aKeyboardEvent ]. aKeyboardEvent shiftPressed ifTrue: [ ^ self lf: aKeyboardEvent ]. aKeyboardEvent commandKeyPressed ifTrue: [ ^ self crlf: aKeyboardEvent ]. ^ self crWithIndent: aKeyboardEvent ]. ((honorCommandKeys := Preferences cmdKeysInText) and: [ typedChar = Character enter ]) ifTrue: [ ^ self dispatchOnEnterWith: aKeyboardEvent ]. "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this conflict, assume that keys other than cursor keys aren't used together with Crtl." ((self class specialShiftCmdKeys includes: aKeyboardEvent keyValue) and: [ aKeyboardEvent keyValue < 27 ]) ifTrue: [ ^ aKeyboardEvent controlKeyPressed ifTrue: [ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ifFalse: [ self perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ]. "backspace, and escape keys (ascii 8 and 27) are command keys" ((honorCommandKeys and: [ aKeyboardEvent commandKeyPressed ]) or: [ self class specialShiftCmdKeys includes: aKeyboardEvent keyValue ]) ifTrue: [ ^ aKeyboardEvent shiftPressed ifTrue: [ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ifFalse: [ self perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ]. "the control key can be used to invoke shift-cmd shortcuts" (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ]) ifTrue: [ ^ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ]. openers := '([{'. closers := ')]}'. (closers includes: typedChar) ifTrue: [ self blinkPrevParen: typedChar. (self class autoEnclose and: [self nextNonwhitespaceCharacter = typedChar]) ifTrue: [ self moveCursor: [ : position | position + 1 ] forward: true select: false. ^ false ] ifFalse: [ result := self normalCharacter: aKeyboardEvent ] ] ifFalse: [ result := self normalCharacter: aKeyboardEvent ]. (self class autoEnclose and: [ openers includes: typedChar ]) ifTrue: [ self addString: (closers at: (openers indexOf: typedChar)) asString ; insertTypeAhead ; moveCursor: [ : position | position - 1 ] forward: false select: false ]. ^ result ---------------------------------------------- It looks like a correct fix to me. Best, Stef From lecteur at zogotounga.net Tue May 19 13:32:35 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Tue May 19 13:32:32 2015 Subject: [squeak-dev] Deceptive focus cue in 4.6 browsers Message-ID: <555B3B73.9040100@zogotounga.net> Try this: - Disable the "Filterable Lists" preference. - Open a new Browser. - Choose any class - Select any message category You get a method template in the text pane. It is highlighted, which makes you think (and it was the behavior so far) that you can type right away your method code. But it is not the case. The message category list still has focus; moreover you need to click inside the code editor to give it focus, which deselect the method template. Annoying. Stef From commits at source.squeak.org Tue May 19 14:18:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 19 14:18:03 2015 Subject: [squeak-dev] The Trunk: MorphicTests-mt.31.mcz Message-ID: Marcel Taeumel uploaded a new version of MorphicTests to project The Trunk: http://source.squeak.org/trunk/MorphicTests-mt.31.mcz ==================== Summary ==================== Name: MorphicTests-mt.31 Author: mt Time: 19 May 2015, 4:17:55.16 pm UUID: 60717262-4e28-a549-a8a2-6918f0a28581 Ancestors: MorphicTests-mt.30 Tests added for scroll panes. =============== Diff against MorphicTests-mt.30 =============== Item was added: + ScrollPaneTest subclass: #ScrollPaneLeftBarTest + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Widgets'! Item was added: + ----- Method: ScrollPaneLeftBarTest class>>shouldInheritSelectors (in category 'testing') ----- + shouldInheritSelectors + + ^ true! Item was added: + ----- Method: ScrollPaneLeftBarTest>>setUp (in category 'running') ----- + setUp + + super setUp. + sut scrollBarOnLeft: true.! Item was added: + ScrollPaneTest subclass: #ScrollPaneRetractableBarsTest + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Widgets'! Item was added: + ----- Method: ScrollPaneRetractableBarsTest class>>shouldInheritSelectors (in category 'testing') ----- + shouldInheritSelectors + + ^ true! Item was added: + ----- Method: ScrollPaneRetractableBarsTest>>setUp (in category 'running') ----- + setUp + + super setUp. + sut retractable: true.! Item was added: + ----- Method: ScrollPaneRetractableBarsTest>>test01ScrollBarPolicyWhenNeeded (in category 'tests') ----- + test01ScrollBarPolicyWhenNeeded + + sut + hScrollBarPolicy: #whenNeeded; + vScrollBarPolicy: #whenNeeded. + + content extent: 100@100. + self refresh. + + self + deny: sut hIsScrollbarShowing; + deny: sut vIsScrollbarShowing. + + content extent: 150@150. + self refresh. + + self + deny: sut hIsScrollbarShowing; + deny: sut vIsScrollbarShowing.! Item was added: + ----- Method: ScrollPaneRetractableBarsTest>>test02ScrollBarPolicyAlways (in category 'tests') ----- + test02ScrollBarPolicyAlways + + sut + hScrollBarPolicy: #always; + vScrollBarPolicy: #always. + + content extent: 50@50. + self refresh. + + self + deny: sut hIsScrollbarShowing; + deny: sut vIsScrollbarShowing. + + content extent: 150@150. + self refresh. + + self + deny: sut hIsScrollbarShowing; + deny: sut vIsScrollbarShowing.! Item was added: + ----- Method: ScrollPaneRetractableBarsTest>>test06ScrollRanges (in category 'tests') ----- + test06ScrollRanges + + content extent: 200@300. + self refresh. + + self + assert: 200 equals: sut hTotalScrollRange; + assert: 300 equals: sut vTotalScrollRange; + assert: 100 equals: sut hLeftoverScrollRange; + assert: 200 equals: sut vLeftoverScrollRange. + + sut hScrollBarValue: 50. + sut vScrollBarValue: 30. + + "Scrolling does not affect the scroll ranges." + self + assert: 200 equals: sut hTotalScrollRange; + assert: 300 equals: sut vTotalScrollRange; + assert: 100 equals: sut hLeftoverScrollRange; + assert: 200 equals: sut vLeftoverScrollRange.! Item was added: + ----- Method: ScrollPaneRetractableBarsTest>>test08ScrollToShow (in category 'tests') ----- + test08ScrollToShow + + content extent: 300@300. + self refresh. + + "1a) Scroll down/right to show bottom right corner." + self scrollToTopLeft. + sut scrollToShow: (50@50 corner: 100@100). + self assert: 0@0 equals: sut scroller offset. + + "1b) Scroll up/left to show top left corner." + self scrollToBottomRight. + sut scrollToShow: (100@100 corner: 150@150). + self assert: 100@100 equals: sut scroller offset. + + "2a) Too big, so show bottom right corner because we scroll down/right." + self scrollToTopLeft. + sut scrollToShow: (0@0 corner: 100@100). + self assert: 0@0 equals: sut scroller offset. + + "2b) Too big, so show top left corner because we scroll up/left." + self scrollToBottomRight. + sut scrollToShow: (50@50 corner: 150@150). + self assert: 50@50 equals: sut scroller offset. + + "3) No negative offsets." + self scrollToTopLeft. + sut scrollToShow: (-10 @ -10 corner: 50@50). + self assert: 0@0 equals: sut scroller offset.! Item was added: + TestCase subclass: #ScrollPaneTest + instanceVariableNames: 'sut content' + classVariableNames: '' + poolDictionaries: '' + category: 'MorphicTests-Widgets'! Item was added: + ----- Method: ScrollPaneTest>>refresh (in category 'running') ----- + refresh + "Since there is now direct communication between the content and the scroll pane, re-layouting as to be explicit." + + sut + resizeScrollBars; + resizeScroller; + setScrollDeltas. + ! Item was added: + ----- Method: ScrollPaneTest>>scrollToBottomRight (in category 'running') ----- + scrollToBottomRight + + sut hScrollBar setValue: sut hScrollBar maximumValue. + sut vScrollBar setValue: sut vScrollBar maximumValue.! Item was added: + ----- Method: ScrollPaneTest>>scrollToTopLeft (in category 'running') ----- + scrollToTopLeft + + sut + hScrollBarValue: 0; + vScrollBarValue: 0; + setScrollDeltas.! Item was added: + ----- Method: ScrollPaneTest>>setUp (in category 'running') ----- + setUp + + super setUp. + sut := ScrollPane new. + sut + retractable: false; + scrollBarOnLeft: false; + extent: 100@100; + borderWidth: 0. "Very important for the math in tests!!" + content := Morph new. + sut scroller addMorph: content.! Item was added: + ----- Method: ScrollPaneTest>>test00SetUp (in category 'tests') ----- + test00SetUp + + self assert: 100@100 equals: sut extent.! Item was added: + ----- Method: ScrollPaneTest>>test01ScrollBarPolicyWhenNeeded (in category 'tests') ----- + test01ScrollBarPolicyWhenNeeded + + sut + hScrollBarPolicy: #whenNeeded; + vScrollBarPolicy: #whenNeeded. + + content extent: 100@100. + self refresh. + + self + deny: sut hIsScrollbarShowing; + deny: sut vIsScrollbarShowing. + + content extent: 150@150. + self refresh. + + self + assert: sut hIsScrollbarShowing; + assert: sut vIsScrollbarShowing.! Item was added: + ----- Method: ScrollPaneTest>>test02ScrollBarPolicyAlways (in category 'tests') ----- + test02ScrollBarPolicyAlways + + sut + hScrollBarPolicy: #always; + vScrollBarPolicy: #always. + + content extent: 50@50. + self refresh. + + self + assert: sut hIsScrollbarShowing; + assert: sut vIsScrollbarShowing. + + content extent: 150@150. + self refresh. + + self + assert: sut hIsScrollbarShowing; + assert: sut vIsScrollbarShowing.! Item was added: + ----- Method: ScrollPaneTest>>test03ScrollBarPolicyNever (in category 'tests') ----- + test03ScrollBarPolicyNever + + sut + hScrollBarPolicy: #never; + vScrollBarPolicy: #never. + + content extent: 50@50. + self refresh. + + self + deny: sut hIsScrollbarShowing; + deny: sut vIsScrollbarShowing. + + content extent: 150@150. + self refresh. + + self + deny: sut hIsScrollbarShowing; + deny: sut vIsScrollbarShowing.! Item was added: + ----- Method: ScrollPaneTest>>test04ScrollingCallIn (in category 'tests') ----- + test04ScrollingCallIn + + content extent: 200@200. + self refresh. + + self + assert: 0 equals: sut hScrollBar value; + assert: 0 equals: sut vScrollBar value; + assert: 0@0 equals: sut scroller offset. + + sut hScrollBar setValue: 50. + sut vScrollBar setValue: 50. + + self + assert: 50 equals: sut hScrollBar value; + assert: 50 equals: sut vScrollBar value; + assert: 50@50 equals: sut scroller offset. + ! Item was added: + ----- Method: ScrollPaneTest>>test05ScrollingCallOut (in category 'tests') ----- + test05ScrollingCallOut + "There is no automatic call-out from pane to scroll bars yet." + + content extent: 200@200. + self refresh. + + self + assert: 0 equals: sut hScrollBar value; + assert: 0 equals: sut vScrollBar value; + assert: 0@0 equals: sut scroller offset. + + sut hScrollBarValue: 50. + sut vScrollBarValue: 50. + + self + assert: 0 equals: sut hScrollBar value; + assert: 0 equals: sut vScrollBar value; + assert: 50@50 equals: sut scroller offset. + + sut hSetScrollDelta. + sut vSetScrollDelta. + + self + assert: 50 equals: sut hScrollBar value; + assert: 50 equals: sut vScrollBar value.! Item was added: + ----- Method: ScrollPaneTest>>test06ScrollRanges (in category 'tests') ----- + test06ScrollRanges + + content extent: 200@300. + self refresh. + + self + assert: 200 equals: sut hTotalScrollRange; + assert: 300 equals: sut vTotalScrollRange; + assert: 100 equals: sut hLeftoverScrollRange - sut scrollBarThickness; + assert: 200 equals: sut vLeftoverScrollRange - sut scrollBarThickness. + + sut hScrollBarValue: 50. + sut vScrollBarValue: 30. + + "Scrolling does not affect the scroll ranges." + self + assert: 200 equals: sut hTotalScrollRange; + assert: 300 equals: sut vTotalScrollRange; + assert: 100 equals: sut hLeftoverScrollRange - sut scrollBarThickness; + assert: 200 equals: sut vLeftoverScrollRange - sut scrollBarThickness. + ! Item was added: + ----- Method: ScrollPaneTest>>test07GuardOffsets (in category 'tests') ----- + test07GuardOffsets + "Scroll bars will never report negative values because they have 0 as minimum. Programmatic access, however, might provide those. Visual appearance should not break then." + + content extent: 200@300. + self refresh. + + sut hScrollBarValue: -10. + sut vScrollBarValue: -20. + + self assert: 0@0 equals: sut scroller offset.! Item was added: + ----- Method: ScrollPaneTest>>test08ScrollToShow (in category 'tests') ----- + test08ScrollToShow + + content extent: 300@300. + self refresh. + + "1a) Scroll down/right to show bottom right corner." + self scrollToTopLeft. + sut scrollToShow: (50@50 corner: 100@100). + self assert: (sut scrollBarThickness @ sut scrollBarThickness) equals: sut scroller offset. + + "1b) Scroll up/left to show top left corner." + self scrollToBottomRight. + sut scrollToShow: (100@100 corner: 150@150). + self assert: 100@100 equals: sut scroller offset. + + "2a) Too big, so show bottom right corner because we scroll down/right." + self scrollToTopLeft. + sut scrollToShow: (0@0 corner: 100@100). + self assert: (sut scrollBarThickness @ sut scrollBarThickness) equals: sut scroller offset. + + "2b) Too big, so show top left corner because we scroll up/left." + self scrollToBottomRight. + sut scrollToShow: (50@50 corner: 150@150). + self assert: 50@50 equals: sut scroller offset. + + "3) No negative offsets." + self scrollToTopLeft. + sut scrollToShow: (-10 @ -10 corner: 50@50). + self assert: 0@0 equals: sut scroller offset.! Item was added: + ----- Method: ScrollPaneTest>>test09HideShowTransition (in category 'tests') ----- + test09HideShowTransition + + content extent: 300@300. + self refresh. + + "1) Horizontal bar not needed anymore." + sut extent: 100@100. + sut vScrollBar setValue: 50. + sut width: content width + sut vScrollBar width. + self assert: sut vLeftoverScrollRange equals: sut vScrollBar maximumValue. + + "2) Vertical bar not needed anymore." + sut extent: 100@100. + sut hScrollBar setValue: 50. + sut height: content height + sut hScrollBar height. + self assert: sut hLeftoverScrollRange equals: sut hScrollBar maximumValue. + ! From commits at source.squeak.org Tue May 19 14:23:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 19 14:23:13 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.982.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.982.mcz ==================== Summary ==================== Name: Morphic-mt.982 Author: mt Time: 19 May 2015, 4:22:25.19 pm UUID: a0f7d55f-83af-db48-9b48-472af0a98f38 Ancestors: Morphic-mt.981 Fixed several bugs related to scrolling in scroll panes, lists, or text fields. This update makes all tests for scroll panes green. =============== Diff against Morphic-mt.981 =============== Item was added: + ----- Method: PluggableListMorph>>offsetToShow: (in category 'scrolling') ----- + offsetToShow: aRectangle + "Due to the approximation of the horizontal scroll range and the primary interaction along the vertical axis, we snap back to 0 on the horizontal axis." + + ^ 0 @ (super offsetToShow: aRectangle) y! Item was changed: ----- Method: ScrollPane>>hScrollBarValue: (in category 'scrolling') ----- hScrollBarValue: scrollValue scroller hasSubmorphs ifFalse: [^ self]. lockOffset == true ifFalse: [ + scroller offset: (scrollValue max: 0) @ scroller offset y]. - scroller offset: scrollValue @scroller offset y]. ! Item was changed: ----- Method: ScrollPane>>handleResizeAction: (in category 'geometry') ----- handleResizeAction: aBlock "Ensure layout properties after resizing takes place." + | oldExtent | + oldExtent := self extent. - | oldW oldH | - oldW := self width. - oldH := self height. aBlock value ifFalse: [^ self]. "Now reset widget sizes" + self extent ~= oldExtent ifTrue: [ + self + resizeScrollBars; + resizeScroller; + setScrollDeltas].! - self - resizeScrollBars; - resizeScroller; - hideOrShowScrollBars. - - "Now resetScrollDeltas where appropriate." - self height ~~ oldH ifTrue: [self vSetScrollDelta]. - self width ~~ oldW ifTrue: [self hSetScrollDelta].! Item was changed: ----- Method: ScrollPane>>offsetToShow: (in category 'scrolling') ----- offsetToShow: aRectangle "Calculate the offset necessary to show the rectangle." + | offset scrollRange target | - | offset scrollRange | offset := scroller offset. + scrollRange := self hTotalScrollRange @ self vTotalScrollRange. + + "Normalize the incoming rectangle." + target := + (scroller width < aRectangle width + ifTrue: [offset x < aRectangle left "Coming from left?" + ifTrue: [aRectangle right - scroller width] + ifFalse: [aRectangle left]] + ifFalse: [aRectangle left]) + @ + (scroller height < aRectangle height + ifTrue: [offset y < aRectangle top "Coming from top?" + ifTrue: [aRectangle bottom - scroller height] + ifFalse: [aRectangle top]] + ifFalse: [aRectangle top]) + corner: + (scroller width < aRectangle width + ifTrue: [offset x + scroller width > aRectangle right "Coming from right?" + ifTrue: [aRectangle left + scroller width] + ifFalse: [aRectangle right]] + ifFalse: [aRectangle right]) + @ + (scroller height < aRectangle height + ifTrue: [offset y + scroller height > aRectangle bottom "Coming from bottom?" + ifTrue: [aRectangle top + scroller height] + ifFalse: [aRectangle bottom]] + ifFalse: [aRectangle bottom]). - scrollRange := self hUnadjustedScrollRange @ self vUnadjustedScrollRange. "Vertical Scrolling" + target top < offset y + ifTrue: [offset := offset x @ target top]. + target bottom > (offset y + scroller height) + ifTrue: [offset := offset x @ (target bottom - scroller height)]. - (aRectangle top - offset y) < 0 - ifTrue: [offset := offset x @ ( - (aRectangle top min: scrollRange y - scroller height))]. - - ((aRectangle bottom - offset y) > scroller height and: [aRectangle height <= scroller height]) - ifTrue: [offset := offset x @ ( - (aRectangle top - scroller height + aRectangle height min: scrollRange y - scroller height))]. "Horizontal Scrolling" + target left < offset x + ifTrue: [offset := target left @ offset y]. + target right > (offset x + scroller width) + ifTrue: [offset := (target right - scroller width) @ offset y]. - (aRectangle left - offset x) < 0 - ifTrue: [offset := ( - (aRectangle left min: scrollRange x - scroller width)) @ offset y]. - - ((aRectangle right - offset x) > scroller width and: [aRectangle width <= scroller width]) - ifTrue: [offset := ( - (aRectangle left - scroller width + aRectangle width min: scrollRange x - scroller width)) @ offset y]. + ^ (offset min: scrollRange - scroller extent) max: 0@0! - ^ offset! Item was changed: ----- Method: ScrollPane>>vScrollBarValue: (in category 'scrolling') ----- vScrollBarValue: scrollValue scroller hasSubmorphs ifFalse: [^ self]. lockOffset == true ifFalse: [ + scroller offset: scroller offset x @ (scrollValue max: 0)]. - scroller offset: scroller offset x @ scrollValue]. ! From Marcel.Taeumel at hpi.de Tue May 19 14:09:33 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 14:26:51 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: References: <1432025619698-4827264.post@n4.nabble.com> Message-ID: <1432044573534-4827381.post@n4.nabble.com> That's not what I meant. You can already enable update for explorer items by monitoring them (use context menu). I extracting/copying code from the inspector for generating the context menu as well as keyboard shortcut callbacks. Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4827381.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 19 14:17:30 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 14:34:49 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <555B3B73.9040100@zogotounga.net> References: <555B3B73.9040100@zogotounga.net> Message-ID: <1432045050852-4827382.post@n4.nabble.com> Hi Stef, a selection in a text field does only slightly indicate keyboard focus (i.e. the darkness of the selection color). I assume that you disabled the preference "mouseOverForKeyboardFocus" ? In that case, I would rather enable "Indicate Keyboard Focus" so that you see were the current keyboard focus is. There will be a rectangle around the morph. As for your example: It is the correct behavior that the message category list still has the keyboard focus because you clicked on a category in that list. However, you are right that clicking into the text pane now removes the selection and thus the "new method template" cannot easily be removed. We will think of something. :) Ideas are welcome. I think that the selection of a text morph that does not have keyboard focus should be much lighter instead of being darker. Best, Marcel -- View this message in context: http://forum.world.st/Deceptive-focus-cue-in-4-6-browsers-tp4827358p4827382.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From commits at source.squeak.org Tue May 19 14:53:53 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 19 14:53:54 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.983.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.983.mcz ==================== Summary ==================== Name: Morphic-mt.983 Author: mt Time: 19 May 2015, 4:53:15.621 pm UUID: bc3f1fa9-6bbc-5844-92b3-4fc4f1d0065d Ancestors: Morphic-mt.982 Make text selection color gray if the text morph has no keyboard focus. Why? Assumption that colorful means active and gray means inactive. We could add this for lists, too. Not sure. =============== Diff against Morphic-mt.982 =============== Item was changed: ----- Method: NewParagraph>>selectionColor (in category 'display') ----- selectionColor | color | Display depth = 1 ifTrue: [^ Color veryLightGray]. Display depth = 2 ifTrue: [^ Color gray]. color := Preferences textHighlightColor. + self focused ifFalse: [color := Color gray: 0.9]. - self focused ifFalse: [color := color alphaMixed: 0.2 with: Color veryVeryLightGray]. ^ color! From Marcel.Taeumel at hpi.de Tue May 19 14:38:14 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 14:55:33 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-mt.983.mcz In-Reply-To: References: Message-ID: <1432046294428-4827398.post@n4.nabble.com> For our community: http://forum.world.st/Deceptive-focus-cue-in-4-6-browsers-td4827358.html :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-mt-983-mcz-tp4827397p4827398.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Tue May 19 14:39:08 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 14:56:26 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <1432045050852-4827382.post@n4.nabble.com> References: <555B3B73.9040100@zogotounga.net> <1432045050852-4827382.post@n4.nabble.com> Message-ID: <1432046348568-4827399.post@n4.nabble.com> Hey Stef, I hopefully could make the focus more clear: http://forum.world.st/The-Trunk-Morphic-mt-983-mcz-td4827397.html#a4827398 Still, the selection is gone once you click for getting focus in the text morph. Best, Marcel -- View this message in context: http://forum.world.st/Deceptive-focus-cue-in-4-6-browsers-tp4827358p4827399.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Tue May 19 14:58:29 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 19 14:58:33 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: <1432044573534-4827381.post@n4.nabble.com> References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> Message-ID: That what I meant, too ;-) Just commenting out the assert: line in the method >> updateInspectorForSelection makes the menu pop up, and everything seems to work. I'm not sure if that breaks something, though... Karl On Tue, May 19, 2015 at 4:09 PM, marcel.taeumel wrote: > That's not what I meant. You can already enable update for explorer items > by > monitoring them (use context menu). > > I extracting/copying code from the inspector for generating the context > menu > as well as keyboard shortcut callbacks. > > Best, > Marcel > > > > > > -- > View this message in context: > http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4827381.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150519/9efbe8b5/attachment.htm From karlramberg at gmail.com Tue May 19 15:03:56 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 19 15:04:00 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <1432046348568-4827399.post@n4.nabble.com> References: <555B3B73.9040100@zogotounga.net> <1432045050852-4827382.post@n4.nabble.com> <1432046348568-4827399.post@n4.nabble.com> Message-ID: I like that On Tue, May 19, 2015 at 4:39 PM, marcel.taeumel wrote: > Hey Stef, > > I hopefully could make the focus more clear: > http://forum.world.st/The-Trunk-Morphic-mt-983-mcz-td4827397.html#a4827398 > > Still, the selection is gone once you click for getting focus in the text > morph. > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/Deceptive-focus-cue-in-4-6-browsers-tp4827358p4827399.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150519/9e1758a0/attachment.htm From Marcel.Taeumel at hpi.de Tue May 19 14:49:10 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 19 15:06:29 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> Message-ID: <1432046950982-4827405.post@n4.nabble.com> Yes, it breaks. Try exploring the ActiveHand and then invoke the menu on keyboardFocus. :) Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4827405.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Tue May 19 15:44:17 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 19 15:44:20 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: <1432046950982-4827405.post@n4.nabble.com> References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> <1432046950982-4827405.post@n4.nabble.com> Message-ID: I get the menu in explorer for ActiveHand keyboardFocus Karl On Tue, May 19, 2015 at 4:49 PM, marcel.taeumel wrote: > Yes, it breaks. Try exploring the ActiveHand and then invoke the menu on > keyboardFocus. :) > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4827405.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150519/0ce15f74/attachment.htm From asqueaker at gmail.com Tue May 19 16:04:50 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 19 16:04:55 2015 Subject: [squeak-dev] Deceptive focus cue in 4.6 browsers In-Reply-To: <555B3B73.9040100@zogotounga.net> References: <555B3B73.9040100@zogotounga.net> Message-ID: On Tue, May 19, 2015 at 8:32 AM, St?phane Rollandin wrote: > Try this: > > - Disable the "Filterable Lists" preference. It seems like the above has nothing to do with the rest of this note..? > - Open a new Browser. > - Choose any class > - Select any message category > > You get a method template in the text pane. It is highlighted, which makes > you think (and it was the behavior so far) that you can type right away your > method code. > > But it is not the case. The message category list still has focus; moreover > you need to click inside the code editor to give it focus, which deselect > the method template. > > Annoying. Totally agree. And, I don't mean to perpetuate a pointless discussion but this is simply the evil of click-for-focus for *every* scenario, not just this scenario. It forces the user to "interact" widgets in ways they don't want to. In the abstract, the easiest way to switch focus when mouseOverForKeyboardFocus is disabled is: Gesture 1: Look for the "least-disruptive" spot somewhere within the widget you want to have keyboard focus (good luck!). Gesture 2: Click that spot. Gesture 3: If that spot caused an undesirable interaction with the widget, click your way out of it, then go to step 4. Gesture 4: Click the spot within the widget where you actually want keyboard focus. So, in your concrete example, the "least disruptive" way might be to: - Open a new Browser. - Choose any class - Select any message category - Click somewhere in the method template. - Click somewhere in the method template once more, but below the bottom of the text so that it will all be selected. Voila! When I came into Squeak more than a decade ago, I had all the habits of a Windows user (e.g., click-for-focus). Over time, I started playing with the available preferences and learned why someone thought they were a good idea -- because they are... :) From lecteur at zogotounga.net Tue May 19 16:13:20 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Tue May 19 16:13:28 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <1432045050852-4827382.post@n4.nabble.com> References: <555B3B73.9040100@zogotounga.net> <1432045050852-4827382.post@n4.nabble.com> Message-ID: <555B6120.7000103@zogotounga.net> > As for your example: It is the correct behavior that the message category > list still has the keyboard focus because you clicked on a category in that > list. It may be the correct behavior, but I'm very much used to the old one :) At now it is really a PITA for me, and I will hack it away in my own images whatever happen in the trunk. Maybe a preference would make sense (I don't mind having a lot of preferences: I think this is the way to go when there are so many little but important workflow points where people disagree). Best, Stef From lecteur at zogotounga.net Tue May 19 16:15:17 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Tue May 19 16:15:16 2015 Subject: [squeak-dev] Deceptive focus cue in 4.6 browsers In-Reply-To: References: <555B3B73.9040100@zogotounga.net> Message-ID: <555B6195.6090904@zogotounga.net> >> Try this: >> >> - Disable the "Filterable Lists" preference. > > It seems like the above has nothing to do with the rest of this note..? I believe you are right :) Stef From lecteur at zogotounga.net Tue May 19 16:18:57 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Tue May 19 16:18:56 2015 Subject: [squeak-dev] Deceptive focus cue in 4.6 browsers In-Reply-To: References: <555B3B73.9040100@zogotounga.net> Message-ID: <555B6271.1010206@zogotounga.net> > So, in your concrete example, the "least disruptive" way might be to: > > - Open a new Browser. > - Choose any class > - Select any message category > - Click somewhere in the method template. > - Click somewhere in the method template once more, but below the > bottom of the text so that it will all be selected. Voila! Yes, that's what I do of course. But then, the method template should not be highlighted in the first place. That's the "deceptive" part. Stef From asqueaker at gmail.com Tue May 19 16:21:56 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 19 16:21:59 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: <1432025407002-4827263.post@n4.nabble.com> References: <1432025407002-4827263.post@n4.nabble.com> Message-ID: That logic is sound except from one POV: which is that #inspect and #explore are used as a debugging tools for _users_. For years, I've been able to simply put one word "inspect" in a strategic place in my application code to help me debug it. Now, I'm forced to add parentheses, cascades and, in some cases, even temp vars (!!) just to avoid getting a SystemWindow tangled up into my domain model. For you as a UI-framework developer, I can understand there might be case or two where you would want to debug SystemWindow stuff. But that is the 0.1% usage case. The 99.9% usage case is Squeak users are interacting with their own domain model and they want to use #inspect as a debugging tool. What do other Smalltalks return from #inspect? If you want to be consistent how about we be consistent with them? On Tue, May 19, 2015 at 3:50 AM, marcel.taeumel wrote: > Hi, there! :) > > I just want to mention and explain, why (Object >> #inspect) now returns the > tool window instead of the object as in 4.5. > > The Tools package adds several convenient methods to the base system: > > Object >> #explore > Object >> #inspect > Object >> #browse > Behavior >> #browse > > All but #inspect returned the created tool. So I went for consistency. But > in particular, those methods should return the tool because because > otherwise the programmer has no simple means to access the created > window/tool programmatically. Model and object are, however, always > accessible (via #model or just #self). > > So if you got code like this: > > self someObjects add: myObject inspect. > > Please change it to: > > self someObjects add: myObject inspect; yourself. > > Or even better to: > > myObject inspect. > self someObjects add: myObject. > > I think that it is good practice/style to use #yourself if you want to get > the receiver back in a chain of calls: > > self myMorphs add: (MyMorph new color: Color yellow; yourself). > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/Tools-Object-inspect-now-returns-the-tool-instead-of-the-object-tp4827263.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From karlramberg at gmail.com Tue May 19 16:22:35 2015 From: karlramberg at gmail.com (karl ramberg) Date: Tue May 19 16:22:38 2015 Subject: [squeak-dev] Deceptive focus cue in 4.6 browsers In-Reply-To: <555B6271.1010206@zogotounga.net> References: <555B3B73.9040100@zogotounga.net> <555B6271.1010206@zogotounga.net> Message-ID: I'll link this just for fun :-) Getting a GUI right is really hard https://xkcd.com/1172/ Karl On Tue, May 19, 2015 at 6:18 PM, St?phane Rollandin wrote: > So, in your concrete example, the "least disruptive" way might be to: >> >> - Open a new Browser. >> - Choose any class >> - Select any message category >> - Click somewhere in the method template. >> - Click somewhere in the method template once more, but below the >> bottom of the text so that it will all be selected. Voila! >> > > Yes, that's what I do of course. But then, the method template should not > be highlighted in the first place. That's the "deceptive" part. > > Stef > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150519/ba3758f2/attachment.htm From lecteur at zogotounga.net Tue May 19 16:28:52 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Tue May 19 16:28:51 2015 Subject: [squeak-dev] Deceptive focus cue in 4.6 browsers In-Reply-To: References: <555B3B73.9040100@zogotounga.net> <555B6271.1010206@zogotounga.net> Message-ID: <555B64C4.7030102@zogotounga.net> > I'll link this just for fun :-) > Getting a GUI right is really hard > > https://xkcd.com/1172/ > > Karl Wait, you're right: I might get Emacs to sort this out for me ! Stef From Das.Linux at gmx.de Tue May 19 16:55:58 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Tue May 19 16:56:02 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: References: <1432025407002-4827263.post@n4.nabble.com> Message-ID: <024E0329-16F5-4B3D-BA2D-5F4938AC0D02@gmx.de> On 19.05.2015, at 18:21, Chris Muller wrote: > That logic is sound except from one POV: which is that #inspect and > #explore are used as a debugging tools for _users_. For years, I've > been able to simply put one word "inspect" in a strategic place in my > application code to help me debug it. Now, I'm forced to add > parentheses, cascades and, in some cases, even temp vars (!!) just to > avoid getting a SystemWindow tangled up into my domain model. > > For you as a UI-framework developer, I can understand there might be > case or two where you would want to debug SystemWindow stuff. But > that is the 0.1% usage case. The 99.9% usage case is Squeak users are > interacting with their own domain model and they want to use #inspect > as a debugging tool. > > What do other Smalltalks return from #inspect? If you want to be > consistent how about we be consistent with them? > That's compatibility and portability, not consistency. Alas, we seldom have them all. -t > On Tue, May 19, 2015 at 3:50 AM, marcel.taeumel wrote: >> Hi, there! :) >> >> I just want to mention and explain, why (Object >> #inspect) now returns the >> tool window instead of the object as in 4.5. >> >> The Tools package adds several convenient methods to the base system: >> >> Object >> #explore >> Object >> #inspect >> Object >> #browse >> Behavior >> #browse >> >> All but #inspect returned the created tool. So I went for consistency. But >> in particular, those methods should return the tool because because >> otherwise the programmer has no simple means to access the created >> window/tool programmatically. Model and object are, however, always >> accessible (via #model or just #self). >> >> So if you got code like this: >> >> self someObjects add: myObject inspect. >> >> Please change it to: >> >> self someObjects add: myObject inspect; yourself. >> >> Or even better to: >> >> myObject inspect. >> self someObjects add: myObject. >> >> I think that it is good practice/style to use #yourself if you want to get >> the receiver back in a chain of calls: >> >> self myMorphs add: (MyMorph new color: Color yellow; yourself). >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: http://forum.world.st/Tools-Object-inspect-now-returns-the-tool-instead-of-the-object-tp4827263.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. From ma.chris.m at gmail.com Tue May 19 19:09:32 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Tue May 19 19:09:36 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: <024E0329-16F5-4B3D-BA2D-5F4938AC0D02@gmx.de> References: <1432025407002-4827263.post@n4.nabble.com> <024E0329-16F5-4B3D-BA2D-5F4938AC0D02@gmx.de> Message-ID: On Tue, May 19, 2015 at 11:55 AM, Tobias Pape wrote: > > On 19.05.2015, at 18:21, Chris Muller wrote: > >> That logic is sound except from one POV: which is that #inspect and >> #explore are used as a debugging tools for _users_. For years, I've >> been able to simply put one word "inspect" in a strategic place in my >> application code to help me debug it. Now, I'm forced to add >> parentheses, cascades and, in some cases, even temp vars (!!) just to >> avoid getting a SystemWindow tangled up into my domain model. >> >> For you as a UI-framework developer, I can understand there might be >> case or two where you would want to debug SystemWindow stuff. But >> that is the 0.1% usage case. The 99.9% usage case is Squeak users are >> interacting with their own domain model and they want to use #inspect >> as a debugging tool. >> >> What do other Smalltalks return from #inspect? If you want to be >> consistent how about we be consistent with them? >> > That's compatibility and portability, not consistency. Well, compatibility and portability refers to production code. If we're talking about the classic Smalltalk debugging tool #inspect, then that is about a consistency of user-experience between the Smalltalk dialects. For some things in Smalltalk, the code _is_ the UI. #inspect is one of those things (as is #printString). > Alas, we seldom have them all. But we can try. :) We know the use-case for wanting classic #inspect, could you (or someone) articulate what is the use-case where I would want a SystemWindow back from inspect? From commits at source.squeak.org Tue May 19 19:56:52 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 19 19:56:54 2015 Subject: [squeak-dev] The Inbox: Morphic-cmm.984.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Inbox: http://source.squeak.org/inbox/Morphic-cmm.984.mcz ==================== Summary ==================== Name: Morphic-cmm.984 Author: cmm Time: 19 May 2015, 2:56:17.688 pm UUID: e1b37491-efb5-4415-bf9f-6f44b577daa0 Ancestors: Morphic-mt.983 Fix the ability to let Morph users set up their own EventHandler to have proper filtering of MouseMoveEvents. =============== Diff against Morphic-mt.983 =============== Item was changed: ----- Method: Morph>>handlesMouseMove: (in category 'event handling') ----- handlesMouseMove: anEvent "Do I want to receive mouseMove: when the hand passes over the receiver? Rules say that by default a morph gets #mouseMove iff * the hand is not dragging anything, + and some button is down, + and the receiver is the current mouse focus." + self eventHandler ifNotNil: [^ self eventHandler handlesMouseMove: anEvent]. anEvent hand hasSubmorphs ifTrue: [ ^ false ]. (anEvent anyButtonPressed and: [ anEvent hand mouseFocus == self ]) ifFalse: [ ^ false ]. ^ true! From commits at source.squeak.org Tue May 19 21:55:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 19 21:55:08 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150519215507.4679.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008701.html Name: Monticello-cmm.616 Ancestors: Monticello-mt.615 - Fix potential security hole with clearPasswords and clearPasswordsAndUsers -- renamed them to #clearCredentials so we don't have my initials in the repositories of this release. - Clarify message about adding historical repository. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008702.html Name: MorphicTests-mt.31 Ancestors: MorphicTests-mt.30 Tests added for scroll panes. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008703.html Name: Morphic-mt.982 Ancestors: Morphic-mt.981 Fixed several bugs related to scrolling in scroll panes, lists, or text fields. This update makes all tests for scroll panes green. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008704.html Name: Morphic-mt.983 Ancestors: Morphic-mt.982 Make text selection color gray if the text morph has no keyboard focus. Why? Assumption that colorful means active and gray means inactive. We could add this for lists, too. Not sure. ============================================= From arielfsqueak at gmail.com Tue May 19 22:11:30 2015 From: arielfsqueak at gmail.com (Ariel Feinerman) Date: Tue May 19 22:11:34 2015 Subject: [squeak-dev] [Bug] ? Rotating a window via halo causes an exception Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: SqueakDebug.log Type: application/octet-stream Size: 13865 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150520/1c107221/SqueakDebug.obj From lewis at mail.msen.com Wed May 20 01:50:04 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed May 20 01:50:08 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: References: <1432025407002-4827263.post@n4.nabble.com> Message-ID: <20150520015004.GA80882@shell.msen.com> On Tue, May 19, 2015 at 11:21:56AM -0500, Chris Muller wrote: > That logic is sound except from one POV: which is that #inspect and > #explore are used as a debugging tools for _users_. For years, I've > been able to simply put one word "inspect" in a strategic place in my > application code to help me debug it. Now, I'm forced to add > parentheses, cascades and, in some cases, even temp vars (!!) just to > avoid getting a SystemWindow tangled up into my domain model. I think that Marcel's design choice is right, even if it is inconvenient for the use case that you describe. The reasons are: 1) It is consistent with the way tool building works in general. 2) It provides a useful return value for #inspect. Answering self is not particularly useful, because I already knew that before I sent #inspect to it. Answering the tool window is useful in various debugging scenarios, and it is not otherwise accessible programatically. > > For you as a UI-framework developer, I can understand there might be > case or two where you would want to debug SystemWindow stuff. But > that is the 0.1% usage case. The 99.9% usage case is Squeak users are > interacting with their own domain model and they want to use #inspect > as a debugging tool. For the use case of embedding #inspect into source code for purposes of debugging, we could trivially add this to serve the same purpose: Object>>inspectYourself self inspect > > What do other Smalltalks return from #inspect? If you want to be > consistent how about we be consistent with them? I do not usually find myself arguing in favor of breaking backward compatibility, but in this case it makes sense and I think it is the right thing to do. Dave > > On Tue, May 19, 2015 at 3:50 AM, marcel.taeumel wrote: > > Hi, there! :) > > > > I just want to mention and explain, why (Object >> #inspect) now returns the > > tool window instead of the object as in 4.5. > > > > The Tools package adds several convenient methods to the base system: > > > > Object >> #explore > > Object >> #inspect > > Object >> #browse > > Behavior >> #browse > > > > All but #inspect returned the created tool. So I went for consistency. But > > in particular, those methods should return the tool because because > > otherwise the programmer has no simple means to access the created > > window/tool programmatically. Model and object are, however, always > > accessible (via #model or just #self). > > > > So if you got code like this: > > > > self someObjects add: myObject inspect. > > > > Please change it to: > > > > self someObjects add: myObject inspect; yourself. > > > > Or even better to: > > > > myObject inspect. > > self someObjects add: myObject. > > > > I think that it is good practice/style to use #yourself if you want to get > > the receiver back in a chain of calls: > > > > self myMorphs add: (MyMorph new color: Color yellow; yourself). > > > > Best, > > Marcel > > > > > > > > -- > > View this message in context: http://forum.world.st/Tools-Object-inspect-now-returns-the-tool-instead-of-the-object-tp4827263.html > > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > From Marcel.Taeumel at hpi.de Wed May 20 05:32:08 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 20 05:49:33 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <555B6120.7000103@zogotounga.net> References: <555B3B73.9040100@zogotounga.net> <1432045050852-4827382.post@n4.nabble.com> <555B6120.7000103@zogotounga.net> Message-ID: <1432099928721-4827527.post@n4.nabble.com> Hi Stef, it does *not* used to be the old one. I just tried it in Squeak 4.5, 4.4, 3.9, and 2.8. Always, there is a selection of the method template visible, but you *cannot* just start typing without repositioning the mouse cursor and maybe clicking into the code pane. Maybe you already had some extensions in your working image? :-) Best, Marcel -- View this message in context: http://forum.world.st/Deceptive-focus-cue-in-4-6-browsers-tp4827358p4827527.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Wed May 20 05:42:00 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 20 05:59:26 2015 Subject: [squeak-dev] Re: [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: References: <1432025407002-4827263.post@n4.nabble.com> Message-ID: <1432100520964-4827530.post@n4.nabble.com> Hi Chris, this sounds like a quite rare corner case for me. Yes, you should add paraenthesis and stuff in such a scenario. Were do you got those statistics from? I would say that 99,98% of Squeak users *scnr* invoke #inspect with a DoIt and do not spread those into their code because those users do not know how often it is executed and will not spoil their GUI with numerous windows popping-up. ;-) Best, Marcel -- View this message in context: http://forum.world.st/Tools-Object-inspect-now-returns-the-tool-instead-of-the-object-tp4827263p4827530.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Wed May 20 05:45:16 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 20 06:02:39 2015 Subject: [squeak-dev] Re: [Bug] ? Rotating a window via halo causes an exception In-Reply-To: References: Message-ID: <1432100716614-4827531.post@n4.nabble.com> Try a newer CogVM. http://www.mirandabanda.org/files/Cog/VM/VM.r3350/ Best, Marcel -- View this message in context: http://forum.world.st/Bug-Rotating-a-window-via-halo-causes-an-exception-tp4827501p4827531.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From lecteur at zogotounga.net Wed May 20 08:47:47 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Wed May 20 08:47:45 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <1432099928721-4827527.post@n4.nabble.com> References: <555B3B73.9040100@zogotounga.net> <1432045050852-4827382.post@n4.nabble.com> <555B6120.7000103@zogotounga.net> <1432099928721-4827527.post@n4.nabble.com> Message-ID: <555C4A33.7010500@zogotounga.net> > Hi Stef, > > it does *not* used to be the old one. I just tried it in Squeak 4.5, 4.4, > 3.9, and 2.8. Always, there is a selection of the method template visible, > but you *cannot* just start typing without repositioning the mouse cursor Yes. > and maybe clicking into the code pane. No. I just tried in a 4.6, update 13700. There you still do not need to click, only reposition the mouse cursor. And when you start typing, the selected template disappears all right. It would be nice to get that back, maybe with a preference. Stef From lecteur at zogotounga.net Wed May 20 08:50:28 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Wed May 20 08:50:22 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: <20150520015004.GA80882@shell.msen.com> References: <1432025407002-4827263.post@n4.nabble.com> <20150520015004.GA80882@shell.msen.com> Message-ID: <555C4AD4.4000604@zogotounga.net> > I think that Marcel's design choice is right, even if it is inconvenient > for the use case that you describe. The reasons are: +1 Stef (also to manifest that I do appreciate the work that Marcel is doing) From Marcel.Taeumel at hpi.de Wed May 20 09:07:25 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 20 09:24:52 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <555C4A33.7010500@zogotounga.net> References: <555B3B73.9040100@zogotounga.net> <1432045050852-4827382.post@n4.nabble.com> <555B6120.7000103@zogotounga.net> <1432099928721-4827527.post@n4.nabble.com> <555C4A33.7010500@zogotounga.net> Message-ID: <1432112845588-4827581.post@n4.nabble.com> Hi Stef, this was due to an inconsistent honoring of the "mouseOverForKeyboardFocus" preference. What about turning on this preference in your image? Best, Marcel -- View this message in context: http://forum.world.st/Deceptive-focus-cue-in-4-6-browsers-tp4827358p4827581.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From lecteur at zogotounga.net Wed May 20 09:50:42 2015 From: lecteur at zogotounga.net (=?windows-1252?Q?St=E9phane_Rollandin?=) Date: Wed May 20 09:50:38 2015 Subject: [squeak-dev] Re: Deceptive focus cue in 4.6 browsers In-Reply-To: <1432112845588-4827581.post@n4.nabble.com> References: <555B3B73.9040100@zogotounga.net> <1432045050852-4827382.post@n4.nabble.com> <555B6120.7000103@zogotounga.net> <1432099928721-4827527.post@n4.nabble.com> <555C4A33.7010500@zogotounga.net> <1432112845588-4827581.post@n4.nabble.com> Message-ID: <555C58F2.5030204@zogotounga.net> > this was due to an inconsistent honoring of the "mouseOverForKeyboardFocus" I understand. The trouble is the current inconsistency: the method template being selected, while there is no way one can make sense of this selection when mouseOverForKeyboardFocus is off. So we should either: - not select the template in the first place (at least when mouseOverForKeyboardFocus is off) - or have the selection stay active when we click to get focus - or get rid of the template altogether - (other options ?) But to me the current state of affair is "deceptive". That's my whole point from the beginning. Stef From arielfsqueak at gmail.com Wed May 20 15:03:57 2015 From: arielfsqueak at gmail.com (Ariel Feinerman) Date: Wed May 20 15:03:59 2015 Subject: [squeak-dev] Re: [Bug] ? Rotating a window via halo causes an exception In-Reply-To: <1432100716614-4827531.post@n4.nabble.com> References: <1432100716614-4827531.post@n4.nabble.com> Message-ID: Of course I mean BorderStyle>>width: color: then I checked it and have found that it implement method . Thank you, I will try On Wed, May 20, 2015 at 8:45 AM, marcel.taeumel wrote: > Try a newer CogVM. > > http://www.mirandabanda.org/files/Cog/VM/VM.r3350/ > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/Bug-Rotating-a-window-via-halo-causes-an-exception-tp4827501p4827531.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -- Best regards, Ariel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150520/10f6a670/attachment.htm From ma.chris.m at gmail.com Wed May 20 17:34:57 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Wed May 20 17:35:01 2015 Subject: [squeak-dev] [Tools] (Object >> #inspect) now returns the tool instead of the object In-Reply-To: <20150520015004.GA80882@shell.msen.com> References: <1432025407002-4827263.post@n4.nabble.com> <20150520015004.GA80882@shell.msen.com> Message-ID: Not a huge deal guys, but some comments still worth noting (below)... On Tue, May 19, 2015 at 8:50 PM, David T. Lewis wrote: > On Tue, May 19, 2015 at 11:21:56AM -0500, Chris Muller wrote: >> That logic is sound except from one POV: which is that #inspect and >> #explore are used as a debugging tools for _users_. For years, I've >> been able to simply put one word "inspect" in a strategic place in my >> application code to help me debug it. Now, I'm forced to add >> parentheses, cascades and, in some cases, even temp vars (!!) just to >> avoid getting a SystemWindow tangled up into my domain model. > > I think that Marcel's design choice is right, even if it is inconvenient > for the use case that you describe. The reasons are: > > 1) It is consistent with the way tool building works in general. It may be consistent with how we _want_ it to work, but the first few examples I checked are all over the map.. Browser open "answers the new Browser model" ChangeSorter open "answers the receiver class" Transcript open "answers the receiver TranscriptStream instance" MCWorkingCopyBrowser open "answers the receiver class" 'abc' inspect "answers a SystemWindow" .... ?? So, if we really care about consistency on this we probably should decide what we want and clean these up at some point.. > 2) It provides a useful return value for #inspect. Answering self is > not particularly useful, because I already knew that before I sent #inspect > to it. Answering self _is_ useful, I already explained why, but Marcel is right, it is pretty rare that I use that particular debugging technique. But, for me at least, wanting a SystemWindow back is even more rare.. The biggest advantage to your way is the opportunity to manipulate the UI window, which we may want to do someday.. >> For you as a UI-framework developer, I can understand there might be >> case or two where you would want to debug SystemWindow stuff. But >> that is the 0.1% usage case. The 99.9% usage case is Squeak users are >> interacting with their own domain model and they want to use #inspect >> as a debugging tool. > > For the use case of embedding #inspect into source code for purposes of > debugging, we could trivially add this to serve the same purpose: > > Object>>inspectYourself > self inspect Or go the other way rather than break a 30-year Smalltalk legacy...? Object>>inspectWindow ^ ToolSet inspect: self :) At a minimum we should decide whether we want to return the UI or the model. From your logic, I guess it would be the UI since that provides access to everything. But at least several #open methods currently seem to be returning the Model.. >> What do other Smalltalks return from #inspect? If you want to be >> consistent how about we be consistent with them? > > I do not usually find myself arguing in favor of breaking backward compatibility, > but in this case it makes sense and I think it is the right thing to do. I get your points, I just think this is kind of like Morph>>#flash -- I always considered it a *debugging tool* to help users develop their apps, and so, for that reason, feel it does not need to follow the same rules as application code -- e.g., a Delay in #flash would be fine, but due to disagreement it remains "clean" but useless to this day... :( From commits at source.squeak.org Wed May 20 18:09:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 20 18:09:29 2015 Subject: [squeak-dev] The Inbox: Monticello-kfr.617.mcz Message-ID: A new version of Monticello was added to project The Inbox: http://source.squeak.org/inbox/Monticello-kfr.617.mcz ==================== Summary ==================== Name: Monticello-kfr.617 Author: kfr Time: 20 May 2015, 8:08:51.778 pm UUID: 0e759ace-d543-f340-a3c2-82dedb54f38d Ancestors: Monticello-cmm.616 Sometimes stepChilden is nil. =============== Diff against Monticello-cmm.616 =============== Item was changed: ----- Method: MCAncestry>>stubAncestryFor:using: (in category 'initialize-release') ----- stubAncestryFor: aMCWorkingCopy using: aMCRepository "childInfo was retrieved from aMCRepository. Replace my ancestry with a Proxy that can retrieve the full tree from these two elements." ancestors := ancestors collect: [ : each | each isMCInfoProxy ifTrue: [ each ] ifFalse: [ MCInfoProxy info: each copyWithTrimmedAncestry workingCopy: aMCWorkingCopy repository: aMCRepository ] ]. + stepChildren := stepChildren ifNotNil:[ :collection | collection collect: - stepChildren := stepChildren collect: [ : each | each isMCInfoProxy ifTrue: [ each ] ifFalse: [ MCInfoProxy info: each copyWithTrimmedAncestry workingCopy: aMCWorkingCopy + repository: aMCRepository ] ]]! - repository: aMCRepository ] ]! From commits at source.squeak.org Wed May 20 19:39:50 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 20 19:39:51 2015 Subject: [squeak-dev] The Inbox: Tools-cmm.626.mcz Message-ID: Chris Muller uploaded a new version of Tools to project The Inbox: http://source.squeak.org/inbox/Tools-cmm.626.mcz ==================== Summary ==================== Name: Tools-cmm.626 Author: cmm Time: 20 May 2015, 2:39:34.146 pm UUID: 14025f66-843c-41dd-8458-de2eccce1166 Ancestors: Tools-mt.625 - Let ToolBuilder open any kind of Object with a consistent API, #open. Objects are opened with an Inspector by default, subclasses may override. - Restore the consistency of #inspect relative to other Smalltalks. =============== Diff against Tools-mt.625 =============== Item was changed: ----- Method: Object>>inspect (in category '*Tools-inspecting') ----- inspect + "Open an Inspector in which the user can examine and change the receiver's variables, and send messages." + self open! - "Create and schedule an Inspector in which the user can examine the receiver's variables." - ^ ToolSet inspect: self! Item was added: + ----- Method: Object>>open (in category '*Tools-inspecting') ----- + open + "Create and schedule an Inspector in which the user can examine the receiver's variables." + ^ ToolSet inspect: self! From asqueaker at gmail.com Wed May 20 21:09:45 2015 From: asqueaker at gmail.com (Chris Muller) Date: Wed May 20 21:09:49 2015 Subject: [squeak-dev] The Inbox: Tools-cmm.626.mcz In-Reply-To: <555ce30c.255e8c0a.7979.ffffa61dSMTPIN_ADDED_MISSING@mx.google.com> References: <555ce30c.255e8c0a.7979.ffffa61dSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: #open is the language of ToolBuiler right? I could hardly stand for Object to overload #open, though.. :\ This is low impact, and the #inspectYourself solution seems easy enough if it ever comes up again. Okay. Good deliberation, thanks. On Wed, May 20, 2015 at 2:39 PM, wrote: > Chris Muller uploaded a new version of Tools to project The Inbox: > http://source.squeak.org/inbox/Tools-cmm.626.mcz > > ==================== Summary ==================== > > Name: Tools-cmm.626 > Author: cmm > Time: 20 May 2015, 2:39:34.146 pm > UUID: 14025f66-843c-41dd-8458-de2eccce1166 > Ancestors: Tools-mt.625 > > - Let ToolBuilder open any kind of Object with a consistent API, #open. Objects are opened with an Inspector by default, subclasses may override. > - Restore the consistency of #inspect relative to other Smalltalks. > > =============== Diff against Tools-mt.625 =============== > > Item was changed: > ----- Method: Object>>inspect (in category '*Tools-inspecting') ----- > inspect > + "Open an Inspector in which the user can examine and change the receiver's variables, and send messages." > + self open! > - "Create and schedule an Inspector in which the user can examine the receiver's variables." > - ^ ToolSet inspect: self! > > Item was added: > + ----- Method: Object>>open (in category '*Tools-inspecting') ----- > + open > + "Create and schedule an Inspector in which the user can examine the receiver's variables." > + ^ ToolSet inspect: self! > > From robert.hirschfeld at gmx.net Wed May 20 21:24:12 2015 From: robert.hirschfeld at gmx.net (Robert Hirschfeld) Date: Wed May 20 21:24:15 2015 Subject: [squeak-dev] Dynamic Languages Symposium (DLS) 2015 | Call for Papers Message-ID: <6496CE29-6CD0-4F47-9793-06ADEED2A075@gmx.net> ----------------------------- C A L L F O R P A P E R S ----------------------------- ======== DLS 2015 =========== 11th Dynamic Languages Symposium 2015 October, 2015 Pittsburgh, Pennsylvania, United States http://DLS2015.inria.fr Co-located with SPLASH 2015 In association with ACM SIGPLAN The 11th Dynamic Languages Symposium (DLS) at SPLASH 2015 is the premier forum for researchers and practitioners to share knowledge and research on dynamic languages, their implementation, and applications. The influence of dynamic languages -- from Lisp to Smalltalk to Python to Javascript -- on real-world practice and research continues to grow. DLS 2015 invites high quality papers reporting original research, innovative contributions, or experience related to dynamic languages, their implementation, and applications. Accepted papers will be published in the ACM Digital Library, and freely available for 2 weeks before and after the event itself. Areas of interest include but are not limited to: Innovative language features and implementation techniques Development and platform support, tools Interesting applications Domain-oriented programming Very late binding, dynamic composition, and run-time adaptation Reflection and meta-programming Software evolution Language symbiosis and multi-paradigm languages Dynamic optimization Hardware support Experience reports and case studies Educational approaches and perspectives Semantics of dynamic languages == Invited Speaker == DLS is pleased to announce a talk by the following invited speaker: Eelco Visser: Declare your Language. == Submissions and proceedings == Submissions should not have been published previously nor under review at other events. Research papers should describe work that advances the current state of the art. Experience papers should be of broad interest and should describe insights gained from substantive practical applications. The program committee will evaluate each contributed paper based on its relevance, significance, clarity, length, and originality. Papers are to be submitted electronically at http://www.easychair.org/conferences?conf=dls15 in PDF format. Submissions must be in the ACM format (see http://www.sigplan.org/authorInformation.htm) and not exceed 12 pages. Authors are reminded that brevity is a virtue. DLS 2015 will run a two-phase reviewing process to help authors make their final papers the best that they can be. After the first round of reviews, papers will be rejected, conditionally accepted, or unconditionally accepted. Conditionally accepted papers will be given a list of issues raised by reviewers. Authors will then submit a revised version of the paper with a cover letter explaining how they have or why they have not addressed these issues. The reviewers will then consider the cover letter and revised paper and recommend final acceptance or rejection. Accepted papers will be published in the ACM Digital Library. Important dates Abstract Submissions: Sun 7 Jun 2015 Full Submissions: Sun 15 Jun 2015 First phase notification: Mon 27 Jul Revisions due: Mon 3 Aug Final notification: Mon 17 Aug Camera ready: Fri 21 21 Aug Program chair Manuel Serrano, Inria Sophia-Antipolis, dls15@easychair.org Program committee Carl Friedrich Bolz, DE William R. Cook, UTexas, USA Jonathan Edwards, MIT, USA John Field, Google, USA Matt Flatt, USA Elisa Gonzalez Boix, Vrije Universiteit, BE Robert Hirschfeld, Hasso-Plattner-Institut Potsdam, DE Benjamin Livshits, Microsoft, USA Crista Lopes, UC Irvine, USA Kevin Millikin, Google, DN James Noble, Victoria University of Wellington, NZ Manuel Serrano, Inria, FR (General chair) Didier Verna, EPITA, FR Jan Vitek, Purdue, USA Joe Politz, Brown University, USA Olivier Tardieu, IBM, USA -- Robert Hirschfeld hirschfeld@acm.org www.hirschfeld.org From ma.chris.m at gmail.com Wed May 20 23:47:02 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Wed May 20 23:47:05 2015 Subject: [squeak-dev] Squeak 4.6 Release Notes Message-ID: I went through every MCVersion since 4.5-13686 to cull this list of highlights. http://wiki.squeak.org/squeak/6192 Quite an impressive tally! Personal thanks and congratulations to all contributors especially Eliot, Levente and Marcel who I seemed to be writing about the most in these notes. - Chris From arielfsqueak at gmail.com Thu May 21 00:09:28 2015 From: arielfsqueak at gmail.com (Ariel Feinerman) Date: Thu May 21 00:09:31 2015 Subject: [squeak-dev] Re: [Bug] ? Rotating a window via halo causes an exception In-Reply-To: References: <1432100716614-4827531.post@n4.nabble.com> Message-ID: Thank you, all works. On Wed, May 20, 2015 at 6:03 PM, Ariel Feinerman wrote: > Of course I mean BorderStyle>>width: color: then I checked it and have > found that it implement method . > > Thank you, I will try > > > > > > On Wed, May 20, 2015 at 8:45 AM, marcel.taeumel > wrote: > >> Try a newer CogVM. >> >> http://www.mirandabanda.org/files/Cog/VM/VM.r3350/ >> >> Best, >> Marcel >> >> >> >> -- >> View this message in context: >> http://forum.world.st/Bug-Rotating-a-window-via-halo-causes-an-exception-tp4827501p4827531.html >> Sent from the Squeak - Dev mailing list archive at Nabble.com. >> >> > > > -- > Best regards, > Ariel > -- Best regards, Ariel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150521/abd44c66/attachment.htm From lewis at mail.msen.com Thu May 21 01:13:49 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Thu May 21 01:13:52 2015 Subject: [squeak-dev] The Inbox: Tools-cmm.626.mcz In-Reply-To: References: <555ce30c.255e8c0a.7979.ffffa61dSMTPIN_ADDED_MISSING@mx.google.com> Message-ID: <20150521011349.GA10254@shell.msen.com> I wanted to check Tools-cmm.626.mcz but it seems to have moved itself to the treated inbox. Is that a mistake? Thanks, Dave On Wed, May 20, 2015 at 04:09:45PM -0500, Chris Muller wrote: > #open is the language of ToolBuiler right? > > I could hardly stand for Object to overload #open, though.. :\ > > This is low impact, and the #inspectYourself solution seems easy > enough if it ever comes up again. Okay. > > Good deliberation, thanks. > > > On Wed, May 20, 2015 at 2:39 PM, wrote: > > Chris Muller uploaded a new version of Tools to project The Inbox: > > http://source.squeak.org/inbox/Tools-cmm.626.mcz > > > > ==================== Summary ==================== > > > > Name: Tools-cmm.626 > > Author: cmm > > Time: 20 May 2015, 2:39:34.146 pm > > UUID: 14025f66-843c-41dd-8458-de2eccce1166 > > Ancestors: Tools-mt.625 > > > > - Let ToolBuilder open any kind of Object with a consistent API, #open. Objects are opened with an Inspector by default, subclasses may override. > > - Restore the consistency of #inspect relative to other Smalltalks. > > > > =============== Diff against Tools-mt.625 =============== > > > > Item was changed: > > ----- Method: Object>>inspect (in category '*Tools-inspecting') ----- > > inspect > > + "Open an Inspector in which the user can examine and change the receiver's variables, and send messages." > > + self open! > > - "Create and schedule an Inspector in which the user can examine the receiver's variables." > > - ^ ToolSet inspect: self! > > > > Item was added: > > + ----- Method: Object>>open (in category '*Tools-inspecting') ----- > > + open > > + "Create and schedule an Inspector in which the user can examine the receiver's variables." > > + ^ ToolSet inspect: self! > > > > From ma.chris.m at gmail.com Thu May 21 01:30:19 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Thu May 21 01:30:24 2015 Subject: [squeak-dev] The Inbox: Tools-cmm.626.mcz In-Reply-To: <20150521011349.GA10254@shell.msen.com> References: <555ce30c.255e8c0a.7979.ffffa61dSMTPIN_ADDED_MISSING@mx.google.com> <20150521011349.GA10254@shell.msen.com> Message-ID: Not a mistake. As I wrote in this thread, we cannot add #open to Object. Although I still don't like the change to #inspect, since I seem to be outvoted, I will just add #inspectYourself in my own image if it comes up again. I also realized, instead of #inspectYourself, I could probably in-line "inspect model object" almost as conveniently as "inspect" for my debugging because they are all unary messages which are first in the evaluation order (relative to binary and keyword messages). On Wed, May 20, 2015 at 8:13 PM, David T. Lewis wrote: > I wanted to check Tools-cmm.626.mcz but it seems to have moved itself to > the treated inbox. Is that a mistake? > > Thanks, > Dave > > On Wed, May 20, 2015 at 04:09:45PM -0500, Chris Muller wrote: >> #open is the language of ToolBuiler right? >> >> I could hardly stand for Object to overload #open, though.. :\ >> >> This is low impact, and the #inspectYourself solution seems easy >> enough if it ever comes up again. Okay. >> >> Good deliberation, thanks. >> >> >> On Wed, May 20, 2015 at 2:39 PM, wrote: >> > Chris Muller uploaded a new version of Tools to project The Inbox: >> > http://source.squeak.org/inbox/Tools-cmm.626.mcz >> > >> > ==================== Summary ==================== >> > >> > Name: Tools-cmm.626 >> > Author: cmm >> > Time: 20 May 2015, 2:39:34.146 pm >> > UUID: 14025f66-843c-41dd-8458-de2eccce1166 >> > Ancestors: Tools-mt.625 >> > >> > - Let ToolBuilder open any kind of Object with a consistent API, #open. Objects are opened with an Inspector by default, subclasses may override. >> > - Restore the consistency of #inspect relative to other Smalltalks. >> > >> > =============== Diff against Tools-mt.625 =============== >> > >> > Item was changed: >> > ----- Method: Object>>inspect (in category '*Tools-inspecting') ----- >> > inspect >> > + "Open an Inspector in which the user can examine and change the receiver's variables, and send messages." >> > + self open! >> > - "Create and schedule an Inspector in which the user can examine the receiver's variables." >> > - ^ ToolSet inspect: self! >> > >> > Item was added: >> > + ----- Method: Object>>open (in category '*Tools-inspecting') ----- >> > + open >> > + "Create and schedule an Inspector in which the user can examine the receiver's variables." >> > + ^ ToolSet inspect: self! >> > >> > From lewis at mail.msen.com Thu May 21 01:35:21 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Thu May 21 01:35:23 2015 Subject: [squeak-dev] The Inbox: Tools-cmm.626.mcz In-Reply-To: References: <555ce30c.255e8c0a.7979.ffffa61dSMTPIN_ADDED_MISSING@mx.google.com> <20150521011349.GA10254@shell.msen.com> Message-ID: <20150521013521.GA14864@shell.msen.com> OK, I see it now. Thanks! Dave On Wed, May 20, 2015 at 08:30:19PM -0500, Chris Muller wrote: > Not a mistake. As I wrote in this thread, we cannot add #open to > Object. Although I still don't like the change to #inspect, since I > seem to be outvoted, I will just add #inspectYourself in my own image > if it comes up again. > > I also realized, instead of #inspectYourself, I could probably in-line > "inspect model object" almost as conveniently as "inspect" for my > debugging because they are all unary messages which are first in the > evaluation order (relative to binary and keyword messages). > > On Wed, May 20, 2015 at 8:13 PM, David T. Lewis wrote: > > I wanted to check Tools-cmm.626.mcz but it seems to have moved itself to > > the treated inbox. Is that a mistake? > > > > Thanks, > > Dave > > > > On Wed, May 20, 2015 at 04:09:45PM -0500, Chris Muller wrote: > >> #open is the language of ToolBuiler right? > >> > >> I could hardly stand for Object to overload #open, though.. :\ > >> > >> This is low impact, and the #inspectYourself solution seems easy > >> enough if it ever comes up again. Okay. > >> > >> Good deliberation, thanks. > >> > >> > >> On Wed, May 20, 2015 at 2:39 PM, wrote: > >> > Chris Muller uploaded a new version of Tools to project The Inbox: > >> > http://source.squeak.org/inbox/Tools-cmm.626.mcz > >> > > >> > ==================== Summary ==================== > >> > > >> > Name: Tools-cmm.626 > >> > Author: cmm > >> > Time: 20 May 2015, 2:39:34.146 pm > >> > UUID: 14025f66-843c-41dd-8458-de2eccce1166 > >> > Ancestors: Tools-mt.625 > >> > > >> > - Let ToolBuilder open any kind of Object with a consistent API, #open. Objects are opened with an Inspector by default, subclasses may override. > >> > - Restore the consistency of #inspect relative to other Smalltalks. > >> > > >> > =============== Diff against Tools-mt.625 =============== > >> > > >> > Item was changed: > >> > ----- Method: Object>>inspect (in category '*Tools-inspecting') ----- > >> > inspect > >> > + "Open an Inspector in which the user can examine and change the receiver's variables, and send messages." > >> > + self open! > >> > - "Create and schedule an Inspector in which the user can examine the receiver's variables." > >> > - ^ ToolSet inspect: self! > >> > > >> > Item was added: > >> > + ----- Method: Object>>open (in category '*Tools-inspecting') ----- > >> > + open > >> > + "Create and schedule an Inspector in which the user can examine the receiver's variables." > >> > + ^ ToolSet inspect: self! > >> > > >> > From lecteur at zogotounga.net Thu May 21 07:27:42 2015 From: lecteur at zogotounga.net (=?UTF-8?B?U3TDqXBoYW5lIFJvbGxhbmRpbg==?=) Date: Thu May 21 07:27:38 2015 Subject: [squeak-dev] Squeak 4.6 Release Notes In-Reply-To: References: Message-ID: <555D88EE.4050006@zogotounga.net> > http://wiki.squeak.org/squeak/6192 Impressive list indeed. Stef From Marcel.Taeumel at hpi.de Thu May 21 07:34:27 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 21 07:51:59 2015 Subject: [squeak-dev] Re: Squeak 4.6 Release Notes In-Reply-To: References: Message-ID: <1432193667211-4827778.post@n4.nabble.com> Wohooo!! ^__^ Big thanks for collecting this list! :) Best, Marcel -- View this message in context: http://forum.world.st/Squeak-4-6-Release-Notes-tp4827750p4827778.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Thu May 21 09:04:09 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 21 09:04:13 2015 Subject: [squeak-dev] Squeak 4.6 Release Notes In-Reply-To: References: Message-ID: Great job collecting this. Two items should be corrected: Saving Morphic Projects: This still does not work HelpBrowser displaying wiki is disabled by default. Karl On Thu, May 21, 2015 at 1:47 AM, Chris Muller wrote: > I went through every MCVersion since 4.5-13686 to cull this list of > highlights. > > http://wiki.squeak.org/squeak/6192 > > Quite an impressive tally! Personal thanks and congratulations to all > contributors especially Eliot, Levente and Marcel who I seemed to be > writing about the most in these notes. > > - Chris > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150521/f6827d27/attachment.htm From karlramberg at gmail.com Thu May 21 09:52:51 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 21 09:52:54 2015 Subject: [squeak-dev] [BUG]ObjectExplorer clicking items in list scrolls list horizontally right Message-ID: When I click a item in the ObjectExplorer list, the whole pane scrolls horizontally to the right, moving pretty much every text row out of pane. This makes using the ObjectExplorer quite tedious and annoying. Open a ObjectExplorer on Browser window to see the behaviour Karl -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150521/7f8c88dc/attachment.htm From Marcel.Taeumel at hpi.de Thu May 21 10:49:29 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 21 11:07:00 2015 Subject: [squeak-dev] Re: [BUG]ObjectExplorer clicking items in list scrolls list horizontally right In-Reply-To: References: Message-ID: <1432205369043-4827811.post@n4.nabble.com> *args* Sorry. :-/ Could you all please check ScrollPaneTests >> textScrollToShow and tell me, whether my assumptions are correct in general? If so, I would just force the left border just as I did in PluggableListMorph >> offsetToShow: Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-clicking-items-in-list-scrolls-list-horizontally-right-tp4827799p4827811.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Thu May 21 12:18:25 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 21 12:18:30 2015 Subject: [squeak-dev] Re: [BUG]ObjectExplorer clicking items in list scrolls list horizontally right In-Reply-To: <1432205369043-4827811.post@n4.nabble.com> References: <1432205369043-4827811.post@n4.nabble.com> Message-ID: The test ScrollPaneTests >>test08ScrollToShow seem right. I think we must force the scroll pane to the left Karl On Thu, May 21, 2015 at 12:49 PM, marcel.taeumel wrote: > *args* Sorry. :-/ > > Could you all please check ScrollPaneTests >> textScrollToShow and tell me, > whether my assumptions are correct in general? If so, I would just force > the > left border just as I did in PluggableListMorph >> offsetToShow: > > Best, > Marcel > > > > -- > View this message in context: > http://forum.world.st/BUG-ObjectExplorer-clicking-items-in-list-scrolls-list-horizontally-right-tp4827799p4827811.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150521/73f747a3/attachment.htm From sean at clipperadams.com Thu May 21 12:20:02 2015 From: sean at clipperadams.com (Sean P. DeNigris) Date: Thu May 21 12:37:36 2015 Subject: [squeak-dev] Re: Squeak 4.6 Release Notes In-Reply-To: References: Message-ID: <1432210802234-4827838.post@n4.nabble.com> Chris Muller-4 wrote > I went through every MCVersion since 4.5-13686 to cull this list of > highlights. Wow, great idea and impressive list :) Congrats and thank you to all! ----- Cheers, Sean -- View this message in context: http://forum.world.st/Squeak-4-6-Release-Notes-tp4827750p4827838.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From eliot.miranda at gmail.com Thu May 21 13:10:38 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 21 13:10:42 2015 Subject: [squeak-dev] Squeak 4.6 Release Notes In-Reply-To: References: Message-ID: Hi Chris, except that Spur is nothing to do with 4.6, so "Spur" in the title is wrong, and become: is not faster, and ObjectHistory still works. We need a separate page for 5.0, which /is/ Spur; it has all the improvements in 4.6, except for ObjectHistory being unsupported, but is faster, with much faster become: and improved GC. Eliot (phone) On May 20, 2015, at 4:47 PM, Chris Muller wrote: > I went through every MCVersion since 4.5-13686 to cull this list of highlights. > > http://wiki.squeak.org/squeak/6192 > > Quite an impressive tally! Personal thanks and congratulations to all > contributors especially Eliot, Levente and Marcel who I seemed to be > writing about the most in these notes. > > - Chris > From commits at source.squeak.org Thu May 21 14:21:16 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 21 14:21:18 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.984.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.984.mcz ==================== Summary ==================== Name: Morphic-mt.984 Author: mt Time: 21 May 2015, 4:20:38.634 pm UUID: 6bfbeda3-2325-6f43-93b6-31515c62212f Ancestors: Morphic-mt.983 Fixes (a regression with) jumpy scrolling behavior in the Object Explorer. =============== Diff against Morphic-mt.983 =============== Item was added: + ----- Method: SimpleHierarchicalListMorph>>offsetToShow: (in category 'scrolling') ----- + offsetToShow: aRectangle + "Focus rectangles are too wide and the view hence jumps to the right. Snap it back to 0 on the horizontal axis." + + ^ 0 @ (super offsetToShow: aRectangle) y! From Marcel.Taeumel at hpi.de Thu May 21 14:04:29 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 21 14:22:03 2015 Subject: [squeak-dev] Re: [BUG]ObjectExplorer clicking items in list scrolls list horizontally right In-Reply-To: References: <1432205369043-4827811.post@n4.nabble.com> Message-ID: <1432217069950-4827874.post@n4.nabble.com> Okay: http://forum.world.st/The-Trunk-Morphic-mt-984-mcz-td4827873.html Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-clicking-items-in-list-scrolls-list-horizontally-right-tp4827799p4827874.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From asqueaker at gmail.com Thu May 21 15:42:27 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu May 21 15:42:31 2015 Subject: [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) Message-ID: > except that Spur is nothing to do with 4.6, so "Spur" in the title is wrong, Ah, I figured that would need some explaining. The word "Spur" on that page refers to the codename of this release. The last time we had a discussion about codenaming this release, we had a smattering of ideas and not much consensus. So, I just went with "Spur" for that moment to get on with the notes until that could be solved. Then, it hit me, if we DIDN'T come up with a codename for this software release then how would we meaningfully refer to it besides the number 4.6? I believe we would say, "that was the release when we made the image ready for Spur", which, in further discussion would naturally contract to "the Spur release" for communication efficiency. I know that Spur is the name of your VM software, but does that mean it cannot also be the name of this release? I think it fits but if you object I did think of another good one I like... > and become: is not faster, and ObjectHistory still works. That was pulled straight from the notes of one of the versions. I'll move it to the 5.0 page. > We need a separate page for 5.0, Yes, we are doing two releases now, one thing at a time please. > which /is/ Spur; it has all the improvements in 4.6, except for ObjectHistory being unsupported, > but is faster, with much faster become: and improved GC. Okay, my plan is for the 5.0 page to _just_ be those items, which is perfect. And since it is the same image contents I thought both 4.6 and 5.0 could be codenamed "Spur" but, if that rubs you the wrong way I have another name picked for 4.6 which I like almost as much. Let me know.. From unoduetre at poczta.onet.pl Thu May 21 16:08:42 2015 From: unoduetre at poczta.onet.pl (Mateusz Grotek) Date: Thu May 21 15:47:45 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: (from asqueaker@gmail.com on Thu May 21 17:42:27 2015) References: Message-ID: <1432224522.12311.0@mglap> > I know that Spur is the name of your VM software, but does that mean > it cannot also be the name of this release? I think it fits but if > you object I did think of another good one I like... > It will certainly create a confusion, that this release is based on Spur. I would be confused! Please, don't do that. From asqueaker at gmail.com Thu May 21 16:15:23 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu May 21 16:15:26 2015 Subject: [squeak-dev] Squeak 4.6 Release Notes In-Reply-To: References: Message-ID: On Thu, May 21, 2015 at 4:04 AM, karl ramberg wrote: > Great job collecting this. > > Two items should be corrected: > > Saving Morphic Projects: This still does not work It doesn't? Shouldn't we fix that for the release? > HelpBrowser displaying wiki is disabled by default. Okay, updated accordingly. From Das.Linux at gmx.de Thu May 21 17:21:39 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 21 17:21:45 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: <1432224522.12311.0@mglap> References: <1432224522.12311.0@mglap> Message-ID: On 21.05.2015, at 18:08, Mateusz Grotek wrote: >> I know that Spur is the name of your VM software, but does that mean >> it cannot also be the name of this release? I think it fits but if >> you object I did think of another good one I like... > > It will certainly create a confusion, that this release is based on Spur. I would be confused! Please, don't do that. +1. There's already confusion of what Spur actually is. I have heard people saying it's a new VM (as in 'This is a Cog VM, this is Spur), or just image format (as in 'Why is there problems with Characters? its only a new image format'), or just object format (as in 'Why can't the interpreter load Spur images and just ignore the Character stuff?'). Best regards -Tobias From karlramberg at gmail.com Thu May 21 17:34:07 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 21 17:34:10 2015 Subject: [squeak-dev] Squeak 4.6 Release Notes In-Reply-To: References: Message-ID: As On Thursday, May 21, 2015, Chris Muller wrote: > On Thu, May 21, 2015 at 4:04 AM, karl ramberg > wrote: > > Great job collecting this. > > > > Two items should be corrected: > > > > Saving Morphic Projects: This still does not work > > It doesn't? Shouldn't we fix that for the release It would be nice if we could fix project saving. I do not understand environments good enough to fix it. Karl > > > HelpBrowser displaying wiki is disabled by default. > > Okay, updated accordingly. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150521/a6ad6d3c/attachment.htm From tim at rowledge.org Thu May 21 17:51:01 2015 From: tim at rowledge.org (tim Rowledge) Date: Thu May 21 17:51:07 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: References: <1432224522.12311.0@mglap> Message-ID: <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> On 21-05-2015, at 10:21 AM, Tobias Pape wrote: > > On 21.05.2015, at 18:08, Mateusz Grotek wrote: > >>> I know that Spur is the name of your VM software, but does that mean >>> it cannot also be the name of this release? I think it fits but if >>> you object I did think of another good one I like... >> >> It will certainly create a confusion, that this release is based on Spur. I would be confused! Please, don't do that. > > +1. There's already confusion of what Spur actually is. How about "This is a dual release; 4.6 continues the 4.5 system with many improvements, whilst 5.0 introduces the Spur memory model and the new VM required to support it. Aside from differences related to making Characters immediates (as with SmallIntegers) the two systems appear the same to programmers" tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful random insult:- All foam, no beer. From Marcel.Taeumel at hpi.de Thu May 21 17:45:03 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 21 18:02:38 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> <1432046950982-4827405.post@n4.nabble.com> Message-ID: <1432230303599-4827933.post@n4.nabble.com> If you remove the assert, you will get a context menu for the wrong object. :) Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4827933.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Thu May 21 19:32:20 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 21 19:32:24 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: <1432230303599-4827933.post@n4.nabble.com> References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> <1432046950982-4827405.post@n4.nabble.com> <1432230303599-4827933.post@n4.nabble.com> Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: Sketch.jpeg Type: image/jpeg Size: 8685 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150521/42a0fecc/Sketch.jpeg From commits at source.squeak.org Thu May 21 21:55:06 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 21 21:55:08 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150521215506.6731.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008705.html Name: Morphic-mt.984 Ancestors: Morphic-mt.983 Fixes (a regression with) jumpy scrolling behavior in the Object Explorer. ============================================= From eliot.miranda at gmail.com Thu May 21 22:25:21 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Thu May 21 22:25:26 2015 Subject: [squeak-dev] New Cog VMs available Message-ID: ... at http://www.mirandabanda.org/files/Cog/VM/VM.r3354 CogVM binaries as per VMMaker.oscog-eem.1318/r3354 Cogit: Fix the performance regression on x86 in r3308 VMMaker.oscog-eem.1178 through the use of XCHG instruction in CogIA32Compiler>>genPushRegisterArgsForNumArgs:. Since SendNumArgsReg is not live with small arity sends it can replace TempReg. Spur: Fix bad C bug in nextInSortedFreeListLink:given:. The result type must be usqInt, otherwise the list can be wrongly terminated and the second compaction pass can segfault. Change printFreeChunk:isNextChunk: to printFreeChunk:printAsTreeNode:, and use it to implement printSortedFreeList. Firm up the checkTraversableSortedFreeList assert routine to check that the list is traversable from lastFreeChunk, not just firstFreeChunk. Make checkTraversableSortedFreeList robust in presence of empty sorted free list. Slang: Make promoteArithmeticTypes:and: obey C99's promotion rules more closely in an effort to generate more stable sources. Types were flipping between sqInt & usqInt for variables that were assigned both types, so that one generation would produce one type and a subsequent one another (Set/Dictionary hashing?). -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150521/474e161b/attachment-0001.htm From hannes.hirzel at gmail.com Fri May 22 09:03:07 2015 From: hannes.hirzel at gmail.com (H. Hirzel) Date: Fri May 22 09:03:08 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> Message-ID: On 5/21/15, tim Rowledge wrote: > > On 21-05-2015, at 10:21 AM, Tobias Pape wrote: > >> >> On 21.05.2015, at 18:08, Mateusz Grotek wrote: >> >>>> I know that Spur is the name of your VM software, but does that mean >>>> it cannot also be the name of this release? I think it fits but if >>>> you object I did think of another good one I like... >>> >>> It will certainly create a confusion, that this release is based on Spur. >>> I would be confused! Please, don't do that. >> >> +1. There's already confusion of what Spur actually is. > > How about > "This is a dual release; 4.6 continues the 4.5 system with many > improvements, whilst 5.0 introduces the Spur memory model and the new VM > required to support it. Aside from differences related to making Characters > immediates (as with SmallIntegers) the two systems appear the same to > programmers" Seems to be like the nucleus of a message which is the base for a communication strategy about the release. --Hannes > > tim > -- > tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim > Useful random insult:- All foam, no beer. > > > > From djm1329 at san.rr.com Fri May 22 16:00:50 2015 From: djm1329 at san.rr.com (Douglas McPherson) Date: Fri May 22 16:00:56 2015 Subject: [squeak-dev] Re: [Pharo-dev] New Cog VMs available In-Reply-To: References: Message-ID: ARM stack.v3 and stack.spur VMs updated accordingly. (The cog.spur VM for ARM builds and image starts successfully, but segfaults pretty quickly ? so I did not upload this one) Doug > On May 21, 2015, at 15:25, Eliot Miranda wrote: > > ... at http://www.mirandabanda.org/files/Cog/VM/VM.r3354 > > CogVM binaries as per VMMaker.oscog-eem.1318/r3354 > > Cogit: > Fix the performance regression on x86 in r3308 VMMaker.oscog-eem.1178 through > the use of XCHG instruction in CogIA32Compiler>>genPushRegisterArgsForNumArgs:. > Since SendNumArgsReg is not live with small arity sends it can replace TempReg. > > Spur: > Fix bad C bug in nextInSortedFreeListLink:given:. The result > type must be usqInt, otherwise the list can be wrongly > terminated and the second compaction pass can segfault. > > Change printFreeChunk:isNextChunk: to printFreeChunk:printAsTreeNode:, and use > it to implement printSortedFreeList. > > Firm up the checkTraversableSortedFreeList assert routine to check that > the list is traversable from lastFreeChunk, not just firstFreeChunk. Make > checkTraversableSortedFreeList robust in presence of empty sorted free list. > > Slang: > Make promoteArithmeticTypes:and: obey C99's promotion rules more closely in an > effort to generate more stable sources. Types were flipping between sqInt & > usqInt for variables that were assigned both types, so that one generation > would produce one type and a subsequent one another (Set/Dictionary hashing?). > -- > best, > Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150522/7a0ff77c/attachment.htm From tim at rowledge.org Fri May 22 16:21:40 2015 From: tim at rowledge.org (tim Rowledge) Date: Fri May 22 16:21:45 2015 Subject: [squeak-dev] Re: [Vm-dev] Re: [Pharo-dev] New Cog VMs available In-Reply-To: References: Message-ID: <9E3F2090-2255-4FD1-BF36-D80EE5EC53EF@rowledge.org> On 22-05-2015, at 9:00 AM, Douglas McPherson wrote: > ARM stack.v3 and stack.spur VMs updated accordingly. > > (The cog.spur VM for ARM builds and image starts successfully, but segfaults pretty quickly ? so I did not upload this one) Smart move :-) It?ll be a while yet before it is really usable. I did manage to demo it for an hour or so at the MakerSpaceNanaimo Smalltalk Caf? on Tuesday, so an awful lot of it works ok. Right now we have an issue with PIC extending? right over the following nmethod. It doesn?t often end happily. tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Useful Latin Phrases:- Catapultam habeo. Nisi pecuniam omnem mihi dabis, ad caput tuum saxum immane mittam = I have a catapult. Give me all the money, or I will fling an enormous rock at your head. From asqueaker at gmail.com Sat May 23 01:31:12 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat May 23 01:31:16 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> Message-ID: I thought about that but then decided we have an opportunity to exercise our release process twice, once for 4.6 and once for 5.0. Treat each relase separately and if we pay attenion to our release process maybe we'll even get to understand and refine it a little. First lets finish up everything for 4.6 including even the news announcement. The announcement should not mention Spur. Then immediately repeat our process for 5.0. Then put out another news release about 5.0 the following week. We don't often get this chance to, as Chris Rock would say, "go pop Pop POP!!" from a marketing perspective. This is one. :) On Thu, May 21, 2015 at 12:51 PM, tim Rowledge wrote: > > On 21-05-2015, at 10:21 AM, Tobias Pape wrote: > >> >> On 21.05.2015, at 18:08, Mateusz Grotek wrote: >> >>>> I know that Spur is the name of your VM software, but does that mean >>>> it cannot also be the name of this release? I think it fits but if >>>> you object I did think of another good one I like... >>> >>> It will certainly create a confusion, that this release is based on Spur. I would be confused! Please, don't do that. >> >> +1. There's already confusion of what Spur actually is. > > How about > "This is a dual release; 4.6 continues the 4.5 system with many improvements, whilst 5.0 introduces the Spur memory model and the new VM required to support it. Aside from differences related to making Characters immediates (as with SmallIntegers) the two systems appear the same to programmers" > > > tim > -- > tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim > Useful random insult:- All foam, no beer. > > > From hannes.hirzel at gmail.com Sat May 23 09:16:57 2015 From: hannes.hirzel at gmail.com (H. Hirzel) Date: Sat May 23 09:17:00 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> Message-ID: On 5/23/15, Chris Muller wrote: > I thought about that but then decided we have an opportunity to > exercise our release process twice, once for 4.6 and once for 5.0. > Treat each relase separately and if we pay attenion to our release > process maybe we'll even get to understand and refine it a little. > > First lets finish up everything for 4.6 including even the news > announcement. The announcement should not mention Spur. Then > immediately repeat our process for 5.0. Then put out another news > release about 5.0 the following week. > > We don't often get this chance to, as Chris Rock would say, "go pop > Pop POP!!" from a marketing perspective. This is one. :) +1 > > On Thu, May 21, 2015 at 12:51 PM, tim Rowledge wrote: >> >> On 21-05-2015, at 10:21 AM, Tobias Pape wrote: >> >>> >>> On 21.05.2015, at 18:08, Mateusz Grotek >>> wrote: >>> >>>>> I know that Spur is the name of your VM software, but does that mean >>>>> it cannot also be the name of this release? I think it fits but if >>>>> you object I did think of another good one I like... >>>> >>>> It will certainly create a confusion, that this release is based on >>>> Spur. I would be confused! Please, don't do that. >>> >>> +1. There's already confusion of what Spur actually is. >> >> How about >> "This is a dual release; 4.6 continues the 4.5 system with many >> improvements, whilst 5.0 introduces the Spur memory model and the new VM >> required to support it. Aside from differences related to making >> Characters immediates (as with SmallIntegers) the two systems appear the >> same to programmers" >> >> >> tim >> -- >> tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim >> Useful random insult:- All foam, no beer. >> >> >> > > From asqueaker at gmail.com Sat May 23 21:40:10 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat May 23 21:40:15 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> Message-ID: > We don't often get this chance to, as Chris Rock would say, "go pop I meant Chris Tucker, of course, not Chris Rock.. https://www.youtube.com/watch?v=5goH0hxUM8A From lewis at mail.msen.com Sun May 24 16:36:02 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun May 24 16:36:03 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 Message-ID: <20150524163602.GA66073@shell.msen.com> UTCDateAndTime is a UTC based implementation of class DateAndTime with one instance variable representing the magnitude of the point in time, and another representing local time zone offset. I recommend loading with the SAR from http://wiki.squeak.org/squeak/6197, as maintaining this in Montecello is problematic. After the 4.6/5.0 release, I would like to suggest moving Chronology out of the Kernel package into its own package, so that changes in Chronology can be maintained in Montecello without conflicting with the rest of Kernel. Spur notes: The Spur image provides a huge performance when loading this set of changes. There are two steps in the loading process in which all DateAndTime instances need to be #becomed into new instances. This is painfully slow in the traditional image (with or without Cog), and it is amazing fast in Spur. That said, there is a bug in the Spur VM (easily resolved I think) that produces incorrect time values. I'll post note about that on vm-dev. I would not recommend using UTCDateAndTime in Spur yet, other than just to see how amazingly fast it is compared to loading the same thing in a non-Spur image. Dave From florin.mateoc at gmail.com Sun May 24 20:04:21 2015 From: florin.mateoc at gmail.com (Florin Mateoc) Date: Sun May 24 20:04:20 2015 Subject: [squeak-dev] #adaptToNumber:andSend: in String Message-ID: <55622EC5.8000907@gmail.com> Hi all, Does anybody know why was the arithmetic protocol added to strings? Evaluating '2' > 1 raises a DNU Evaluating 1 < '2' answers true. Even worse, 1 < '2bla' answers true as well. This (the successful part) happens because of the implementation mentioned in the subject (plus numeric parser's behavior). That implementation was not part of the original protocol, as written by Dan Ingalls in 1998. It seems to have been added by Yoshiki in 2004. Was this done to address something in particular? To me it seems inconsistent, as in the above examples. There are other inconsistencies as well: the arithmetic operators mostly work - they were implemented in String by Yoshiki in 2004 as well, but e.g. 1s + '2' fails ('2' + 1s succeeds). And there is further funny behavior: '2' + 1 evaluates to 3 '2' + '1' evaluates to '3' '2foo' + '1bar' evaluates to '3' Presumably the failures could be made to work as well, but is this desirable? To me this seems as bad and arbitrary as Javascript's automatic conversions (there both comparisons mentioned above succeed, but 1 + '2' evaluates to '12' and '2' + 1 evaluates to '21', whereas 1 - '2' evaluates to -1 and '2' - 1 evaluates to 1. Just beautiful!). Best, Florin From leves at elte.hu Sun May 24 21:22:48 2015 From: leves at elte.hu (Levente Uzonyi) Date: Sun May 24 21:22:55 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 In-Reply-To: <20150524163602.GA66073@shell.msen.com> References: <20150524163602.GA66073@shell.msen.com> Message-ID: On Sun, 24 May 2015, David T. Lewis wrote: > UTCDateAndTime is a UTC based implementation of class DateAndTime with > one instance variable representing the magnitude of the point in time, > and another representing local time zone offset. > > I recommend loading with the SAR from http://wiki.squeak.org/squeak/6197, > as maintaining this in Montecello is problematic. > > After the 4.6/5.0 release, I would like to suggest moving Chronology out > of the Kernel package into its own package, so that changes in Chronology > can be maintained in Montecello without conflicting with the rest of Kernel. > > Spur notes: The Spur image provides a huge performance when loading this > set of changes. There are two steps in the loading process in which all > DateAndTime instances need to be #becomed into new instances. This is > painfully slow in the traditional image (with or without Cog), and it is > amazing fast in Spur. Similar speed can be achieved in V3 images (on any VM), if all instances are exchanged in one shot. In LX-2.2.cs: | oldInstances newInstances | oldInstances := DateAndTime allInstances, TimeStamp allInstances. newInstances := oldInstances collect: [ :each | each class == DateAndTime ifTrue: [ each asLXDateAndTime ] ifFalse: [ each asLXTimeStamp ] ]. oldInstances elementsForwardIdentityTo: newInstances. And in LX-4.1.cs: | oldInstances newInstances | oldInstances := LXDateAndTime allInstances, LXTimeStamp allInstances. newInstances := oldInstances collect: [ :each | each class == LXDateAndTime ifTrue: [ each asDateAndTime ] ifFalse: [ each asTimeStamp ] ]. oldInstances elementsForwardIdentityTo: newInstances. Levente > > That said, there is a bug in the Spur VM (easily resolved I think) that > produces incorrect time values. I'll post note about that on vm-dev. I > would not recommend using UTCDateAndTime in Spur yet, other than just > to see how amazingly fast it is compared to loading the same thing in > a non-Spur image. > > Dave > > > From karlramberg at gmail.com Mon May 25 08:22:53 2015 From: karlramberg at gmail.com (karl ramberg) Date: Mon May 25 08:22:58 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> <1432046950982-4827405.post@n4.nabble.com> <1432230303599-4827933.post@n4.nabble.com> Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: SimpleHierarchicalListMorph-mouseMove.st Type: application/octet-stream Size: 728 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150525/ce45d053/SimpleHierarchicalListMorph-mouseMove.obj From Marcel.Taeumel at hpi.de Mon May 25 08:57:45 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Mon May 25 09:15:47 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> <1432046950982-4827405.post@n4.nabble.com> <1432230303599-4827933.post@n4.nabble.com> Message-ID: <1432544265553-4828430.post@n4.nabble.com> Thank you. I will take a look at it. Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4828430.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From lewis at mail.msen.com Mon May 25 14:48:20 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Mon May 25 14:48:22 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 In-Reply-To: References: <20150524163602.GA66073@shell.msen.com> Message-ID: <20150525144820.GA84891@shell.msen.com> On Sun, May 24, 2015 at 11:22:48PM +0200, Levente Uzonyi wrote: > On Sun, 24 May 2015, David T. Lewis wrote: > > >UTCDateAndTime is a UTC based implementation of class DateAndTime with > >one instance variable representing the magnitude of the point in time, > >and another representing local time zone offset. > > > >I recommend loading with the SAR from http://wiki.squeak.org/squeak/6197, > >as maintaining this in Montecello is problematic. > > > >After the 4.6/5.0 release, I would like to suggest moving Chronology out > >of the Kernel package into its own package, so that changes in Chronology > >can be maintained in Montecello without conflicting with the rest of > >Kernel. > > > >Spur notes: The Spur image provides a huge performance when loading this > >set of changes. There are two steps in the loading process in which all > >DateAndTime instances need to be #becomed into new instances. This is > >painfully slow in the traditional image (with or without Cog), and it is > >amazing fast in Spur. > > Similar speed can be achieved in V3 images (on any VM), if all instances > are exchanged in one shot. In LX-2.2.cs: > > | oldInstances newInstances | > oldInstances := DateAndTime allInstances, TimeStamp allInstances. > newInstances := oldInstances collect: [ :each | > each class == DateAndTime > ifTrue: [ each asLXDateAndTime ] > ifFalse: [ each asLXTimeStamp ] ]. > oldInstances elementsForwardIdentityTo: newInstances. > > And in LX-4.1.cs: > > | oldInstances newInstances | > oldInstances := LXDateAndTime allInstances, LXTimeStamp allInstances. > newInstances := oldInstances collect: [ :each | > each class == LXDateAndTime > ifTrue: [ each asDateAndTime ] > ifFalse: [ each asTimeStamp ] ]. > oldInstances elementsForwardIdentityTo: newInstances. Levente, Thank you! I was not aware of that. Dave From asqueaker at gmail.com Mon May 25 16:23:50 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 25 16:23:53 2015 Subject: [squeak-dev] #adaptToNumber:andSend: in String In-Reply-To: <55622EC5.8000907@gmail.com> References: <55622EC5.8000907@gmail.com> Message-ID: On Sun, May 24, 2015 at 3:04 PM, Florin Mateoc wrote: > Hi all, > > Does anybody know why was the arithmetic protocol added to strings? > > Evaluating '2' > 1 raises a DNU > Evaluating 1 < '2' answers true. Even worse, 1 < '2bla' answers true as well. > > This (the successful part) happens because of the implementation mentioned in the subject (plus numeric parser's > behavior). That implementation was not part of the original protocol, as written by Dan Ingalls in 1998. It seems to > have been added by Yoshiki in 2004. Was this done to address something in particular? To me it seems inconsistent, as in > the above examples. There are other inconsistencies as well: the arithmetic operators mostly work - they were > implemented in String by Yoshiki in 2004 as well, but e.g. 1s + '2' fails ('2' + 1s succeeds). And there is further > funny behavior: > > '2' + 1 evaluates to 3 > '2' + '1' evaluates to '3' > '2foo' + '1bar' evaluates to '3' > > > Presumably the failures could be made to work as well, but is this desirable? To me this seems as bad and arbitrary as > Javascript's automatic conversions (there both comparisons mentioned above succeed, but 1 + '2' evaluates to '12' and > '2' + 1 evaluates to '21', whereas 1 - '2' evaluates to -1 and '2' - 1 evaluates to 1. Just beautiful!). +1. Isn't it crazy? We should push to fix it in 5.1. From tim.olson.mail at gmail.com Mon May 25 16:46:39 2015 From: tim.olson.mail at gmail.com (Tim Olson) Date: Mon May 25 16:46:44 2015 Subject: [squeak-dev] #adaptToNumber:andSend: in String In-Reply-To: <55622EC5.8000907@gmail.com> References: <55622EC5.8000907@gmail.com> Message-ID: <2BFE1A63-94EF-42F8-8FBE-2F9B13DF088B@gmail.com> On May 24, 2015, at 3:04 PM, Florin Mateoc wrote: > Hi all, > > Does anybody know why was the arithmetic protocol added to strings? I remember it having something to do with the Etoys environment. ? tim From lewis at mail.msen.com Mon May 25 17:18:20 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Mon May 25 17:18:23 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 In-Reply-To: <20150525144820.GA84891@shell.msen.com> References: <20150524163602.GA66073@shell.msen.com> <20150525144820.GA84891@shell.msen.com> Message-ID: <20150525171820.GA6718@shell.msen.com> On Mon, May 25, 2015 at 10:48:20AM -0400, David T. Lewis wrote: > On Sun, May 24, 2015 at 11:22:48PM +0200, Levente Uzonyi wrote: > > On Sun, 24 May 2015, David T. Lewis wrote: > > > > >UTCDateAndTime is a UTC based implementation of class DateAndTime with > > >one instance variable representing the magnitude of the point in time, > > >and another representing local time zone offset. > > > > > >I recommend loading with the SAR from http://wiki.squeak.org/squeak/6197, > > >as maintaining this in Montecello is problematic. > > > > > >After the 4.6/5.0 release, I would like to suggest moving Chronology out > > >of the Kernel package into its own package, so that changes in Chronology > > >can be maintained in Montecello without conflicting with the rest of > > >Kernel. > > > > > >Spur notes: The Spur image provides a huge performance when loading this > > >set of changes. There are two steps in the loading process in which all > > >DateAndTime instances need to be #becomed into new instances. This is > > >painfully slow in the traditional image (with or without Cog), and it is > > >amazing fast in Spur. > > > > Similar speed can be achieved in V3 images (on any VM), if all instances > > are exchanged in one shot. In LX-2.2.cs: > > > > | oldInstances newInstances | > > oldInstances := DateAndTime allInstances, TimeStamp allInstances. > > newInstances := oldInstances collect: [ :each | > > each class == DateAndTime > > ifTrue: [ each asLXDateAndTime ] > > ifFalse: [ each asLXTimeStamp ] ]. > > oldInstances elementsForwardIdentityTo: newInstances. > > > > And in LX-4.1.cs: > > > > | oldInstances newInstances | > > oldInstances := LXDateAndTime allInstances, LXTimeStamp allInstances. > > newInstances := oldInstances collect: [ :each | > > each class == LXDateAndTime > > ifTrue: [ each asDateAndTime ] > > ifFalse: [ each asTimeStamp ] ]. > > oldInstances elementsForwardIdentityTo: newInstances. > > Levente, > > Thank you! I was not aware of that. I updated the SAR at http://wiki.squeak.org/squeak/6197. Indeed it now loads very quickly in a V3 image. Dave From asqueaker at gmail.com Mon May 25 18:31:33 2015 From: asqueaker at gmail.com (Chris Muller) Date: Mon May 25 18:31:36 2015 Subject: [squeak-dev] "Stirrup" needs your help Message-ID: Eliot decided he wants to codename 4.6 "Stirrup" and 5.0 "Spur". We are just a few steps from releasing we just need some volunteer(s) help. You know, if we could coordinate and change the Jenkins build to produce the actual release image we want, along with new .sources and .changes, and possibly even an All-In-One, maybe that's a release process we could really like..? From leves at elte.hu Tue May 26 01:36:29 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 26 01:36:32 2015 Subject: [squeak-dev] "Stirrup" needs your help In-Reply-To: References: Message-ID: On Mon, 25 May 2015, Chris Muller wrote: > Eliot decided he wants to codename 4.6 "Stirrup" and 5.0 "Spur". > > We are just a few steps from releasing we just need some volunteer(s) help. > > You know, if we could coordinate and change the Jenkins build to > produce the actual release image we want, along with new .sources and > .changes, and possibly even an All-In-One, maybe that's a release > process we could really like..? That's exactly what the ReleaseSqueakTrunk job should be doing. http://build.squeak.org/job/ReleaseSqueakTrunk/ Levente > > From leves at elte.hu Tue May 26 01:39:01 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 26 01:39:05 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 In-Reply-To: <20150525171820.GA6718@shell.msen.com> References: <20150524163602.GA66073@shell.msen.com> <20150525144820.GA84891@shell.msen.com> <20150525171820.GA6718@shell.msen.com> Message-ID: On Mon, 25 May 2015, David T. Lewis wrote: > On Mon, May 25, 2015 at 10:48:20AM -0400, David T. Lewis wrote: >> On Sun, May 24, 2015 at 11:22:48PM +0200, Levente Uzonyi wrote: >>> On Sun, 24 May 2015, David T. Lewis wrote: >>> >>>> UTCDateAndTime is a UTC based implementation of class DateAndTime with >>>> one instance variable representing the magnitude of the point in time, >>>> and another representing local time zone offset. >>>> >>>> I recommend loading with the SAR from http://wiki.squeak.org/squeak/6197, >>>> as maintaining this in Montecello is problematic. >>>> >>>> After the 4.6/5.0 release, I would like to suggest moving Chronology out >>>> of the Kernel package into its own package, so that changes in Chronology >>>> can be maintained in Montecello without conflicting with the rest of >>>> Kernel. >>>> >>>> Spur notes: The Spur image provides a huge performance when loading this >>>> set of changes. There are two steps in the loading process in which all >>>> DateAndTime instances need to be #becomed into new instances. This is >>>> painfully slow in the traditional image (with or without Cog), and it is >>>> amazing fast in Spur. >>> >>> Similar speed can be achieved in V3 images (on any VM), if all instances >>> are exchanged in one shot. In LX-2.2.cs: >>> >>> | oldInstances newInstances | >>> oldInstances := DateAndTime allInstances, TimeStamp allInstances. >>> newInstances := oldInstances collect: [ :each | >>> each class == DateAndTime >>> ifTrue: [ each asLXDateAndTime ] >>> ifFalse: [ each asLXTimeStamp ] ]. >>> oldInstances elementsForwardIdentityTo: newInstances. >>> >>> And in LX-4.1.cs: >>> >>> | oldInstances newInstances | >>> oldInstances := LXDateAndTime allInstances, LXTimeStamp allInstances. >>> newInstances := oldInstances collect: [ :each | >>> each class == LXDateAndTime >>> ifTrue: [ each asDateAndTime ] >>> ifFalse: [ each asTimeStamp ] ]. >>> oldInstances elementsForwardIdentityTo: newInstances. >> >> Levente, >> >> Thank you! I was not aware of that. > > I updated the SAR at http://wiki.squeak.org/squeak/6197. Indeed it now loads > very quickly in a V3 image. Cool. I've got another change set, which makes instance creation more than twice as fast: http://leves.web.elte.hu/squeak/DateAndTimeCreationSpeedup.1.cs Levente > > Dave > > From Marcel.Taeumel at hpi.de Tue May 26 07:54:28 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Tue May 26 08:12:34 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> Message-ID: <1432626868058-4828560.post@n4.nabble.com> Hi, there! :) -1 for Stirrup -1 for Spur What about colors? http://www.colourlovers.com/web/blog/2008/04/22/all-120-crayon-names-color-codes-and-fun-facts "Mountain Meadow" representing the solid code base in Squeak 4.6. "Sky Blue" referring to the new image format and hence future (sight/direction/view) of Squeak resp. Squeak 5.0. Many people might not get technical metaphors anyway. :D Just my two cents. ;) Best, Marcel -- View this message in context: http://forum.world.st/4-6-Codename-was-Squeak-4-6-Release-Notes-tp4827896p4828560.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From frank.shearar at gmail.com Tue May 26 09:44:14 2015 From: frank.shearar at gmail.com (Frank Shearar) Date: Tue May 26 09:44:17 2015 Subject: [squeak-dev] "Stirrup" needs your help In-Reply-To: References: Message-ID: On 26 May 2015 at 02:36, Levente Uzonyi wrote: > On Mon, 25 May 2015, Chris Muller wrote: > >> Eliot decided he wants to codename 4.6 "Stirrup" and 5.0 "Spur". >> >> We are just a few steps from releasing we just need some volunteer(s) >> help. >> >> You know, if we could coordinate and change the Jenkins build to >> produce the actual release image we want, along with new .sources and >> .changes, and possibly even an All-In-One, maybe that's a release >> process we could really like..? > > > That's exactly what the ReleaseSqueakTrunk job should be doing. > http://build.squeak.org/job/ReleaseSqueakTrunk/ Indeed. Which currently doesn't work, because I'm getting 503s on build.squeak.org URIs. frank > Levente From lewis at mail.msen.com Tue May 26 14:49:26 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Tue May 26 14:49:27 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 In-Reply-To: References: <20150524163602.GA66073@shell.msen.com> <20150525144820.GA84891@shell.msen.com> <20150525171820.GA6718@shell.msen.com> Message-ID: <14951.136.2.1.104.1432651766.squirrel@webmail.msen.com> Excellent, thank you Levente. I'll make the update as soon as I can (late today). FYI, I added you as developer on the SS3 repository http://ss3.gemstone.com/ss/UTCDateAndTime.html (but that does not mean I expect you to keep it updated, doing this in MC is a pain right now). Dave > On Mon, 25 May 2015, David T. Lewis wrote: > >> On Mon, May 25, 2015 at 10:48:20AM -0400, David T. Lewis wrote: >>> On Sun, May 24, 2015 at 11:22:48PM +0200, Levente Uzonyi wrote: >>>> On Sun, 24 May 2015, David T. Lewis wrote: >>>> >>>>> UTCDateAndTime is a UTC based implementation of class DateAndTime >>>>> with >>>>> one instance variable representing the magnitude of the point in >>>>> time, >>>>> and another representing local time zone offset. >>>>> >>>>> I recommend loading with the SAR from >>>>> http://wiki.squeak.org/squeak/6197, >>>>> as maintaining this in Montecello is problematic. >>>>> >>>>> After the 4.6/5.0 release, I would like to suggest moving Chronology >>>>> out >>>>> of the Kernel package into its own package, so that changes in >>>>> Chronology >>>>> can be maintained in Montecello without conflicting with the rest of >>>>> Kernel. >>>>> >>>>> Spur notes: The Spur image provides a huge performance when loading >>>>> this >>>>> set of changes. There are two steps in the loading process in which >>>>> all >>>>> DateAndTime instances need to be #becomed into new instances. This is >>>>> painfully slow in the traditional image (with or without Cog), and it >>>>> is >>>>> amazing fast in Spur. >>>> >>>> Similar speed can be achieved in V3 images (on any VM), if all >>>> instances >>>> are exchanged in one shot. In LX-2.2.cs: >>>> >>>> | oldInstances newInstances | >>>> oldInstances := DateAndTime allInstances, TimeStamp allInstances. >>>> newInstances := oldInstances collect: [ :each | >>>> each class == DateAndTime >>>> ifTrue: [ each asLXDateAndTime ] >>>> ifFalse: [ each asLXTimeStamp ] ]. >>>> oldInstances elementsForwardIdentityTo: newInstances. >>>> >>>> And in LX-4.1.cs: >>>> >>>> | oldInstances newInstances | >>>> oldInstances := LXDateAndTime allInstances, LXTimeStamp allInstances. >>>> newInstances := oldInstances collect: [ :each | >>>> each class == LXDateAndTime >>>> ifTrue: [ each asDateAndTime ] >>>> ifFalse: [ each asTimeStamp ] ]. >>>> oldInstances elementsForwardIdentityTo: newInstances. >>> >>> Levente, >>> >>> Thank you! I was not aware of that. >> >> I updated the SAR at http://wiki.squeak.org/squeak/6197. Indeed it now >> loads >> very quickly in a V3 image. > > Cool. I've got another change set, which makes instance creation more than > twice as fast: > http://leves.web.elte.hu/squeak/DateAndTimeCreationSpeedup.1.cs > > Levente > >> >> Dave >> >> > From timfelgentreff at gmail.com Tue May 26 15:27:21 2015 From: timfelgentreff at gmail.com (timfelgentreff) Date: Tue May 26 15:45:32 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: <1432626868058-4828560.post@n4.nabble.com> References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> <1432626868058-4828560.post@n4.nabble.com> Message-ID: <1432654041546-4828676.post@n4.nabble.com> I agree with Tobias that naming a release "Spur" could create confusion. However, I'm not good with names anyway and always refer to any release by its number. -- View this message in context: http://forum.world.st/4-6-Codename-was-Squeak-4-6-Release-Notes-tp4827896p4828676.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From asqueaker at gmail.com Tue May 26 15:47:23 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 26 15:47:27 2015 Subject: [squeak-dev] "Stirrup" needs your help In-Reply-To: References: Message-ID: >> Eliot decided he wants to codename 4.6 "Stirrup" and 5.0 "Spur". >> >> We are just a few steps from releasing we just need some volunteer(s) >> help. >> >> You know, if we could coordinate and change the Jenkins build to >> produce the actual release image we want, along with new .sources and >> .changes, and possibly even an All-In-One, maybe that's a release >> process we could really like..? > > > That's exactly what the ReleaseSqueakTrunk job should be doing. > http://build.squeak.org/job/ReleaseSqueakTrunk/ Yes, "should". If it would do all those things then we'd basically be ready to "release" any day we ever wanted with nothing more than a FTP upload, website update, and a news release. Unfortunately, it just produces a 4.5 trunk image, not a 4.6 release image, and it doesn't make new .changes, nor new .sources, and no new All-In-One (or does it?). What would it take to get us there? From asqueaker at gmail.com Tue May 26 15:48:29 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 26 15:48:32 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: <1432626868058-4828560.post@n4.nabble.com> References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> <1432626868058-4828560.post@n4.nabble.com> Message-ID: They are not my favorite names either but they reasonably fit -- the "Stirrup" will get you into the saddle, "Spurs" to make it go.. :-/ Codenames are relatively unimportant, so rather than burn any more time and energy talking about them lets just go with this and move forward. On Tue, May 26, 2015 at 2:54 AM, marcel.taeumel wrote: > Hi, there! :) > > -1 for Stirrup > -1 for Spur > > What about colors? > http://www.colourlovers.com/web/blog/2008/04/22/all-120-crayon-names-color-codes-and-fun-facts > > "Mountain Meadow" representing the solid code base in Squeak 4.6. > "Sky Blue" referring to the new image format and hence future > (sight/direction/view) of Squeak resp. Squeak 5.0. > > Many people might not get technical metaphors anyway. :D > > Just my two cents. ;) > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/4-6-Codename-was-Squeak-4-6-Release-Notes-tp4827896p4828560.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From leves at elte.hu Tue May 26 16:04:22 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 26 16:04:25 2015 Subject: [squeak-dev] "Stirrup" needs your help In-Reply-To: References: Message-ID: On Tue, 26 May 2015, Chris Muller wrote: >>> Eliot decided he wants to codename 4.6 "Stirrup" and 5.0 "Spur". >>> >>> We are just a few steps from releasing we just need some volunteer(s) >>> help. >>> >>> You know, if we could coordinate and change the Jenkins build to >>> produce the actual release image we want, along with new .sources and >>> .changes, and possibly even an All-In-One, maybe that's a release >>> process we could really like..? >> >> >> That's exactly what the ReleaseSqueakTrunk job should be doing. >> http://build.squeak.org/job/ReleaseSqueakTrunk/ > > Yes, "should". If it would do all those things then we'd basically be > ready to "release" any day we ever wanted with nothing more than a FTP > upload, website update, and a news release. > > Unfortunately, it just produces a 4.5 trunk image, not a 4.6 release > image, and it doesn't make new .changes, nor new .sources, and no new > All-In-One (or does it?). It's the SqueakTrunk job which produces Trunk images. IIRC the ReleaseSqueakTrunk job takes the Trunk image from SqueakTrunk. Then it runs the code in ReleaseBuilder class, which is responsible for the image-side changes for the next release. I'm not sure what you'd like to do with the .sources and .changes files. > > What would it take to get us there? IMHO the best would be to build the All-In-One in another job - triggered by ReleaseSqueakTrunk. Levente From leves at elte.hu Tue May 26 16:05:48 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 26 16:05:56 2015 Subject: [Box-Admins] Re: [squeak-dev] "Stirrup" needs your help In-Reply-To: References: Message-ID: On Tue, 26 May 2015, Frank Shearar wrote: > On 26 May 2015 at 02:36, Levente Uzonyi wrote: >> On Mon, 25 May 2015, Chris Muller wrote: >> >>> Eliot decided he wants to codename 4.6 "Stirrup" and 5.0 "Spur". >>> >>> We are just a few steps from releasing we just need some volunteer(s) >>> help. >>> >>> You know, if we could coordinate and change the Jenkins build to >>> produce the actual release image we want, along with new .sources and >>> .changes, and possibly even an All-In-One, maybe that's a release >>> process we could really like..? >> >> >> That's exactly what the ReleaseSqueakTrunk job should be doing. >> http://build.squeak.org/job/ReleaseSqueakTrunk/ > > Indeed. Which currently doesn't work, because I'm getting 503s on > build.squeak.org URIs. Yep, it went down (the second time this week), but it's up again. Levente > > frank > >> Levente > From commits at source.squeak.org Tue May 26 21:27:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Tue May 26 21:27:13 2015 Subject: [squeak-dev] The Inbox: SqueakSSL-Core-ul.30.mcz Message-ID: Levente Uzonyi uploaded a new version of SqueakSSL-Core to project The Inbox: http://source.squeak.org/inbox/SqueakSSL-Core-ul.30.mcz ==================== Summary ==================== Name: SqueakSSL-Core-ul.30 Author: ul Time: 26 May 2015, 11:25:11.058 pm UUID: 0b33ea1e-9f1c-4e22-94f0-a4ac34d3982c Ancestors: SqueakSSL-Core-ul.29 - Use the DNS names from the certificate's SAN extension (#subjectAltNameDNS) in #verifyCert:. - Use case insensitive host name comparison in #verifyCert:. =============== Diff against SqueakSSL-Core-ul.29 =============== Item was added: + ----- Method: SecureSocketStream>>verify:matchesHost: (in category 'initialize') ----- + verify: nameInCertificate matchesHost: hostName + "This comparison must be case insensitive." + + | lowercaseNameInCertificate lowercaseHostName | + lowercaseNameInCertificate := nameInCertificate asLowercase. + lowercaseHostName := hostName asLowercase. + lowercaseNameInCertificate = lowercaseHostName ifTrue: [ ^true ]. + "Check if it's a wildcard name." + (lowercaseNameInCertificate beginsWith: '*.') ifFalse: [ ^false ]. + ^lowercaseHostName endsWith: lowercaseNameInCertificate allButFirst! Item was changed: ----- Method: SecureSocketStream>>verifyCert: (in category 'initialize') ----- verifyCert: hostName "Verifies the cert state and host name" | certFlags | certFlags := self certState. certFlags = -1 ifTrue:[^self certError: 'No certificate was provided' code: -1]. certFlags = 0 ifFalse:[self certError: 'Invalid certificate' code: certFlags]. + (self verify: ssl peerName matchesHost: hostName) ifTrue: [ ^self ]. + ssl subjectAltNameDNS ifNotNil: [ :subjectAltNameDNS | + subjectAltNameDNS splitBy: ',' do: [ :alternateName | + (self verify: alternateName matchesHost: hostName) ifTrue: [ ^self ] ] ]. + self certError: 'Host name mismatch' code: -1! - (ssl peerName match: hostName) - ifFalse:[self certError: 'Host name mismatch' code: -1].! Item was added: + ----- Method: SqueakSSL>>subjectAltNameDNS (in category 'accessing') ----- + subjectAltNameDNS + "Returns a string containing the DNS names of the certificate's SAN extension, or nil if there are none. + The method only returns the names if the certificate has been verified." + + ^self primitiveSSL: handle getStringProperty: 3! From leves at elte.hu Tue May 26 21:55:42 2015 From: leves at elte.hu (Levente Uzonyi) Date: Tue May 26 21:55:47 2015 Subject: [squeak-dev] SqueakSSL + SAN certificates Message-ID: Hi All, I've implemented support for reading the domain names from the certificate's SAN extension[1] in SqueakSSL. The image side code is in the Inbox[2]. It is backwards compatible -- everything works as before without the VM changes. I've also uploaded the modified files[3][4] for the unix platform, and a diff[5] (which somehow doesn't include the changes of the .h file). The VM support code for other platforms are to be done. These changes fix the failing SqueakSSL test in the Trunk, so I suggest including the .mcz file in the 4.6 release. Levente [1] https://en.wikipedia.org/wiki/SubjectAltName [2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt From asqueaker at gmail.com Tue May 26 22:53:02 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 26 22:53:04 2015 Subject: [squeak-dev] is it okay to signal a Semaphore from multiple processes? Message-ID: I want to kick off several HTTP downloads simulatenously. Only after ALL are done do I want to continue. So to test if I could use a single Semaphore to control this: | s numberOfDownloads | numberOfDownloads := 5. s:=Semaphore new. 1 to: numberOfDownloads do: [ : n | [(Delay forMilliseconds: (200 to: 700) atRandom) wait. "<--- simulates HTTP download" s signal ] fork ]. 1 to: numberOfDownloads do: [ : n | s wait ]. "... continue ..." So I have multiple processes sending #signal to the Semaphore is that okay? I didn't experience any problems with the above test even upping the numberOfDownloads to 500. If #signal were written as: excessSignals := excessSignals + 1 then it might be a problem but its a primitive so it is atomic and therefore should be fine, right? From asqueaker at gmail.com Tue May 26 23:00:14 2015 From: asqueaker at gmail.com (Chris Muller) Date: Tue May 26 23:00:18 2015 Subject: [squeak-dev] Re: is it okay to signal a Semaphore from multiple processes? In-Reply-To: References: Message-ID: Sheesh, sorry, of course it is. This is the whole purpose of Semaphore.. On Tue, May 26, 2015 at 5:53 PM, Chris Muller wrote: > I want to kick off several HTTP downloads simulatenously. Only after > ALL are done do I want to continue. So to test if I could use a > single Semaphore to control this: > > | s numberOfDownloads | > numberOfDownloads := 5. > s:=Semaphore new. > 1 to: numberOfDownloads do: [ : n | > [(Delay forMilliseconds: (200 to: 700) atRandom) wait. "<--- > simulates HTTP download" > s signal ] fork ]. > 1 to: numberOfDownloads do: [ : n | s wait ]. > "... continue ..." > > So I have multiple processes sending #signal to the Semaphore is that > okay? I didn't experience any problems with the above test even > upping the numberOfDownloads to 500. > > If #signal were written as: > > excessSignals := excessSignals + 1 > > then it might be a problem but its a primitive so it is atomic and > therefore should be fine, right? From lewis at mail.msen.com Wed May 27 00:52:13 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed May 27 00:52:16 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 In-Reply-To: References: <20150524163602.GA66073@shell.msen.com> <20150525144820.GA84891@shell.msen.com> <20150525171820.GA6718@shell.msen.com> Message-ID: <20150527005213.GA18021@shell.msen.com> On Tue, May 26, 2015 at 03:39:01AM +0200, Levente Uzonyi wrote: > On Mon, 25 May 2015, David T. Lewis wrote: > > >On Mon, May 25, 2015 at 10:48:20AM -0400, David T. Lewis wrote: > >>On Sun, May 24, 2015 at 11:22:48PM +0200, Levente Uzonyi wrote: > >>>On Sun, 24 May 2015, David T. Lewis wrote: > >>> > >>>>UTCDateAndTime is a UTC based implementation of class DateAndTime with > >>>>one instance variable representing the magnitude of the point in time, > >>>>and another representing local time zone offset. > >>>> > >>>>I recommend loading with the SAR from > >>>>http://wiki.squeak.org/squeak/6197, > >>>>as maintaining this in Montecello is problematic. > >>>> > >>>>After the 4.6/5.0 release, I would like to suggest moving Chronology out > >>>>of the Kernel package into its own package, so that changes in > >>>>Chronology > >>>>can be maintained in Montecello without conflicting with the rest of > >>>>Kernel. > >>>> > >>>>Spur notes: The Spur image provides a huge performance when loading this > >>>>set of changes. There are two steps in the loading process in which all > >>>>DateAndTime instances need to be #becomed into new instances. This is > >>>>painfully slow in the traditional image (with or without Cog), and it is > >>>>amazing fast in Spur. > >>> > >>>Similar speed can be achieved in V3 images (on any VM), if all instances > >>>are exchanged in one shot. In LX-2.2.cs: > >>> > >>>| oldInstances newInstances | > >>>oldInstances := DateAndTime allInstances, TimeStamp allInstances. > >>>newInstances := oldInstances collect: [ :each | > >>> each class == DateAndTime > >>> ifTrue: [ each asLXDateAndTime ] > >>> ifFalse: [ each asLXTimeStamp ] ]. > >>>oldInstances elementsForwardIdentityTo: newInstances. > >>> > >>>And in LX-4.1.cs: > >>> > >>>| oldInstances newInstances | > >>>oldInstances := LXDateAndTime allInstances, LXTimeStamp allInstances. > >>>newInstances := oldInstances collect: [ :each | > >>> each class == LXDateAndTime > >>> ifTrue: [ each asDateAndTime ] > >>> ifFalse: [ each asTimeStamp ] ]. > >>>oldInstances elementsForwardIdentityTo: newInstances. > >> > >>Levente, > >> > >>Thank you! I was not aware of that. > > > >I updated the SAR at http://wiki.squeak.org/squeak/6197. Indeed it now > >loads > >very quickly in a V3 image. > > Cool. I've got another change set, which makes instance creation more than > twice as fast: > http://leves.web.elte.hu/squeak/DateAndTimeCreationSpeedup.1.cs Thanks Levente, Added to the SAR at http://wiki.squeak.org/squeak/6197 and to the repository at http://ss3.gemstone.com/ss/UTCDateAndTime.html. I also updated #hasUtcPrim for startup processing to use your #primPosixMicrosecondClockWithOffset change. Dave From leves at elte.hu Wed May 27 01:23:42 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 27 01:23:45 2015 Subject: [squeak-dev] Re: [Vm-dev] SqueakSSL + SAN certificates In-Reply-To: <7810ABD8-2D02-4FDB-AE17-9BC14A0E07A5@hartl.name> References: <7810ABD8-2D02-4FDB-AE17-9BC14A0E07A5@hartl.name> Message-ID: If it were possible, then there would be no need to add this. Levente On Wed, 27 May 2015, Norbert Hartl wrote: > > Sounds great! Is it possible to access to whole certificate data as well? > > Norbert > >> Am 26.05.2015 um 23:55 schrieb Levente Uzonyi : >> >> Hi All, >> >> I've implemented support for reading the domain names from the certificate's SAN extension[1] in SqueakSSL. >> The image side code is in the Inbox[2]. It is backwards compatible -- everything works as before without the VM changes. >> I've also uploaded the modified files[3][4] for the unix platform, and a diff[5] (which somehow doesn't include the changes of the .h file). >> >> The VM support code for other platforms are to be done. >> >> These changes fix the failing SqueakSSL test in the Trunk, so I suggest including the .mcz file in the 4.6 release. >> >> Levente >> >> [1] https://en.wikipedia.org/wiki/SubjectAltName >> [2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html >> [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h >> [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c >> [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt > > From leves at elte.hu Wed May 27 01:24:17 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 27 01:24:22 2015 Subject: [squeak-dev] UTCDateAndTime updated for Squeak 4.6/5.0 In-Reply-To: <20150527005213.GA18021@shell.msen.com> References: <20150524163602.GA66073@shell.msen.com> <20150525144820.GA84891@shell.msen.com> <20150525171820.GA6718@shell.msen.com> <20150527005213.GA18021@shell.msen.com> Message-ID: On Tue, 26 May 2015, David T. Lewis wrote: > On Tue, May 26, 2015 at 03:39:01AM +0200, Levente Uzonyi wrote: >> On Mon, 25 May 2015, David T. Lewis wrote: >> >>> On Mon, May 25, 2015 at 10:48:20AM -0400, David T. Lewis wrote: >>>> On Sun, May 24, 2015 at 11:22:48PM +0200, Levente Uzonyi wrote: >>>>> On Sun, 24 May 2015, David T. Lewis wrote: >>>>> >>>>>> UTCDateAndTime is a UTC based implementation of class DateAndTime with >>>>>> one instance variable representing the magnitude of the point in time, >>>>>> and another representing local time zone offset. >>>>>> >>>>>> I recommend loading with the SAR from >>>>>> http://wiki.squeak.org/squeak/6197, >>>>>> as maintaining this in Montecello is problematic. >>>>>> >>>>>> After the 4.6/5.0 release, I would like to suggest moving Chronology out >>>>>> of the Kernel package into its own package, so that changes in >>>>>> Chronology >>>>>> can be maintained in Montecello without conflicting with the rest of >>>>>> Kernel. >>>>>> >>>>>> Spur notes: The Spur image provides a huge performance when loading this >>>>>> set of changes. There are two steps in the loading process in which all >>>>>> DateAndTime instances need to be #becomed into new instances. This is >>>>>> painfully slow in the traditional image (with or without Cog), and it is >>>>>> amazing fast in Spur. >>>>> >>>>> Similar speed can be achieved in V3 images (on any VM), if all instances >>>>> are exchanged in one shot. In LX-2.2.cs: >>>>> >>>>> | oldInstances newInstances | >>>>> oldInstances := DateAndTime allInstances, TimeStamp allInstances. >>>>> newInstances := oldInstances collect: [ :each | >>>>> each class == DateAndTime >>>>> ifTrue: [ each asLXDateAndTime ] >>>>> ifFalse: [ each asLXTimeStamp ] ]. >>>>> oldInstances elementsForwardIdentityTo: newInstances. >>>>> >>>>> And in LX-4.1.cs: >>>>> >>>>> | oldInstances newInstances | >>>>> oldInstances := LXDateAndTime allInstances, LXTimeStamp allInstances. >>>>> newInstances := oldInstances collect: [ :each | >>>>> each class == LXDateAndTime >>>>> ifTrue: [ each asDateAndTime ] >>>>> ifFalse: [ each asTimeStamp ] ]. >>>>> oldInstances elementsForwardIdentityTo: newInstances. >>>> >>>> Levente, >>>> >>>> Thank you! I was not aware of that. >>> >>> I updated the SAR at http://wiki.squeak.org/squeak/6197. Indeed it now >>> loads >>> very quickly in a V3 image. >> >> Cool. I've got another change set, which makes instance creation more than >> twice as fast: >> http://leves.web.elte.hu/squeak/DateAndTimeCreationSpeedup.1.cs > > Thanks Levente, > > Added to the SAR at http://wiki.squeak.org/squeak/6197 and to the repository > at http://ss3.gemstone.com/ss/UTCDateAndTime.html. I also updated #hasUtcPrim > for startup processing to use your #primPosixMicrosecondClockWithOffset change. Thanks Dave! Levente From leves at elte.hu Wed May 27 01:47:13 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 27 01:47:17 2015 Subject: [squeak-dev] SqueakSSL + SAN certificates In-Reply-To: References: Message-ID: I fixed a bug in the C code and reuploded it, along with a precompiled version of the plugin: http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL It's built on Ubuntu 14.04 with GCC 4.8.2. Levente On Tue, 26 May 2015, Levente Uzonyi wrote: > Hi All, > > I've implemented support for reading the domain names from the certificate's > SAN extension[1] in SqueakSSL. > The image side code is in the Inbox[2]. It is backwards compatible -- > everything works as before without the VM changes. > I've also uploaded the modified files[3][4] for the unix platform, and a > diff[5] (which somehow doesn't include the changes of the .h file). > > The VM support code for other platforms are to be done. > > These changes fix the failing SqueakSSL test in the Trunk, so I suggest > including the .mcz file in the 4.6 release. > > Levente > > [1] https://en.wikipedia.org/wiki/SubjectAltName > [2] > http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html > [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h > [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c > [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt > > From saijanai at gmail.com Wed May 27 02:06:37 2015 From: saijanai at gmail.com (Lawson English) Date: Wed May 27 02:06:38 2015 Subject: [squeak-dev] How can I find Kernel-bf.899 and then USE it? Message-ID: Title says it all. Thanks Lawson > > - > > ------------------------------ > > On 10.02.2015, at 13:39, David T. Lewis > wrote: > > >* On Tue, Feb 10, 2015 at 02:39:19AM -0700, Lawson English wrote: > *>>* This bit of code fails at numb := 1024: > *>> >>* error: Cannot truncate this number > *>> >>* numb := 1024. > *>>* 1 to: numb do: [:n||test| test:=(2 raisedTo: n) -1. (test isPrime) > *>>* ifTrue: [Transcript show: n; tab; show: test;cr]] > *>> >>* #isProbablyPrime fails with the same number. > *>> >> >>* numb := 1023. > *>>* works for both. > *>> > >* It looks like a problem in random number generation. It is failing in > *>* LargePositiveInteger>>atRandom which somehow results in the random > *>* generator producing a value of Float infinity. > *> >* Dave > * > Yep. Random>>nextInt: does not work for really large ints. Fixed in Kernel-bf.899. > > - Bert - > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150526/069ce787/attachment.htm From leves at elte.hu Wed May 27 02:59:21 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 27 02:59:25 2015 Subject: [squeak-dev] How can I find Kernel-bf.899 and then USE it? In-Reply-To: References: Message-ID: It's in The Trunk repository on source.squeak.org. If you have an up-to-date Trunk image, then you're already using it. If not, you can get the latest here: http://build.squeak.org/job/SqueakTrunk/lastSuccessfulBuild/artifact/target/TrunkImage.zip Please note that this code has not been released yet, and the PRNG implementation has been changed since Kernel-bf.899. Levente On Tue, 26 May 2015, Lawson English wrote: > Title says it all.? > > Thanks > > Lawson? > o > > ________________________________________________________________________________________________________________________________________________________________________________________________________________ > > On 10.02.2015, at 13:39, David T. Lewis wrote: > > > > On Tue, Feb 10, 2015 at 02:39:19AM -0700, Lawson English wrote: > >> This bit of code fails at numb := 1024: > >> > >> error: Cannot truncate this number > >> > >> numb := 1024. > >> 1 to: numb do: [:n||test| test:=(2 raisedTo: n) -1. (test isPrime) > >> ifTrue: [Transcript show: n; tab; show: test;cr]] > >> > >> #isProbablyPrime fails with the same number. > >> > >> > >> numb := 1023. > >> works for both. > >> > > > > It looks like a problem in random number generation. It is failing in > > LargePositiveInteger>>atRandom which somehow results in the random > > generator producing a value of Float infinity. > > > > Dave > > Yep. Random>>nextInt: does not work for really large ints. Fixed in Kernel-bf.899. > > - Bert - > > > From Marcel.Taeumel at hpi.de Wed May 27 05:29:48 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 27 05:48:01 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> <1432626868058-4828560.post@n4.nabble.com> Message-ID: <1432704588391-4828797.post@n4.nabble.com> Or just don't use a codename this time... ;-) Best, Marcel -- View this message in context: http://forum.world.st/4-6-Codename-was-Squeak-4-6-Release-Notes-tp4827896p4828797.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Das.Linux at gmx.de Wed May 27 06:27:18 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Wed May 27 06:27:22 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: <1432626868058-4828560.post@n4.nabble.com> References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> <1432626868058-4828560.post@n4.nabble.com> Message-ID: <35F5D4FC-4821-42DB-BEC5-E6A80ACA3AD7@gmx.de> Hi, On 26.05.2015, at 09:54, marcel.taeumel wrote: > -1 for Stirrup > -1 for Spur I have the same feeling about this code names. Especially the overlap of Spur and Spur does not sound right to me. Marcel's idea of colors is fun. Side note: I find the code names for pypy quite amusing [1]. Maybe we can draw inspiration there? They are not technology related, which I find a good thing. Best regards -Tobias [1]: https://pypy.readthedocs.org/en/latest/index-of-release-notes.html From robert.hirschfeld at gmx.net Wed May 27 06:36:26 2015 From: robert.hirschfeld at gmx.net (Robert Hirschfeld) Date: Wed May 27 06:36:30 2015 Subject: [SPAM] [squeak-dev] 4.6 Codename (was: Squeak 4.6 Release Notes) In-Reply-To: <35F5D4FC-4821-42DB-BEC5-E6A80ACA3AD7@gmx.de> References: <1432224522.12311.0@mglap> <8F2C3998-BD79-46A2-B1CE-542398BCB1CF@rowledge.org> <1432626868058-4828560.post@n4.nabble.com> <35F5D4FC-4821-42DB-BEC5-E6A80ACA3AD7@gmx.de> Message-ID: <331DFF76-F044-48A1-BD21-F66CDB57D37C@gmx.net> I agree. Best, Robert --- www.hirschfeld.org > On May 27, 2015, at 08:27, Tobias Pape wrote: > > Hi, > >> On 26.05.2015, at 09:54, marcel.taeumel wrote: >> >> -1 for Stirrup >> -1 for Spur > > > I have the same feeling about this code names. > Especially the overlap of Spur and Spur does not > sound right to me. Marcel's idea of colors is > fun. > Side note: I find the code names for pypy quite > amusing [1]. Maybe we can draw inspiration there? > They are not technology related, which I find > a good thing. > > > Best regards > -Tobias > > [1]: https://pypy.readthedocs.org/en/latest/index-of-release-notes.html > From edgardec2005 at gmail.com Wed May 27 08:51:31 2015 From: edgardec2005 at gmail.com (Edgar J. De Cleene) Date: Wed May 27 08:51:41 2015 Subject: [squeak-dev] [OT} About a Web Page Framework For Cuis Message-ID: Chris: I found some page of you as Juan answer on Cuis list. The .image can't be found. Several of us in Cuis list wish it if you could put it somewhere. Also I working in GreenNeon and wish you add me to SqueakSource and let me send ideas and code for having in it > On 5/26/2015 7:49 AM, Edgar J. De Cleene wrote: >> https://websela.wordpress.com/2013/06/16/a-web-framework-for-cuis/ >> >> If any have the image described here , let me know. >> >> Edgar > > Hi Edgar, > > I'm pretty sure that brasspen is Chris Cunnington. You might email him: > Chris Cunnington gmail.com> with copy to squeak-dev. > > Cheers, > Juan Vuletich Best wishes. Edgar From brasspen at gmail.com Wed May 27 11:11:45 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Wed May 27 11:11:50 2015 Subject: [squeak-dev] [OT} About a Web Page Framework For Cuis Message-ID: <7AABFB72-4407-4F84-B424-7CB4DFAB8C6E@gmail.com> >I found some page of you as Juan answer on Cuis list. >The .image can't be found. Whoa. I haven?t thought about this for ages. Give me a couple of days. I?ll get back to you. Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150527/fd4225ed/attachment.htm From edgardec2005 at gmail.com Wed May 27 12:05:10 2015 From: edgardec2005 at gmail.com (Edgar J. De Cleene) Date: Wed May 27 12:05:18 2015 Subject: [squeak-dev] [OT} About a Web Page Framework For Cuis In-Reply-To: <7AABFB72-4407-4F84-B424-7CB4DFAB8C6E@gmail.com> Message-ID: On 5/27/15, 8:11 AM, "Chris Cunnington" wrote: > Whoa. I haven?t thought about this for ages. Give me a couple of days. I?ll > get back to you. > > Chris Very thanks, take your time Edgar -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150527/52fab291/attachment.htm From commits at source.squeak.org Wed May 27 12:14:28 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 27 12:14:31 2015 Subject: [squeak-dev] The Trunk: Morphic-mt.985.mcz Message-ID: Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.985.mcz ==================== Summary ==================== Name: Morphic-mt.985 Author: mt Time: 27 May 2015, 2:13:49.6 pm UUID: c315a5f2-a6af-d34c-809a-c14702a96423 Ancestors: Morphic-mt.984 Fixes a bug with the selection highlight in ObjectExplorer (and all other tools that use a tree widget). See: http://forum.world.st/BUG-ObjectExplorer-menu-td4827121.html =============== Diff against Morphic-mt.984 =============== Item was changed: ----- Method: SimpleHierarchicalListMorph>>mouseDown: (in category 'event handling') ----- mouseDown: evt | aMorph selectors | aMorph := self itemFromPoint: evt position. evt yellowButtonPressed "First check for option (menu) click" ifTrue: [ (PluggableListMorph menuRequestUpdatesSelection and: [model okToChange]) ifTrue: [ aMorph == selectedMorph ifFalse: [self setSelectedMorph: aMorph]]. ^ self yellowButtonActivity: evt shiftPressed]. (aMorph notNil and:[aMorph inToggleArea: (aMorph point: evt position from: self)]) ifTrue:[^self toggleExpandedState: aMorph event: evt]. aMorph ifNil:[^super mouseDown: evt]. + aMorph highlightForMouseDown. + self setProperty: #highlightedMorph toValue: aMorph. + selectors := Array with: #click: with: nil with: nil with: (self dragEnabled ifTrue:[#startDrag:] ifFalse:[nil]). evt hand waitForClicksOrDrag: self event: evt selectors: selectors threshold: HandMorph dragThreshold "pixels".! Item was changed: ----- Method: SimpleHierarchicalListMorph>>mouseUp: (in category 'event handling') ----- + mouseUp: event + + | clickedMorph highlightedMorph | + clickedMorph := self itemFromPoint: event position. + highlightedMorph := self valueOfProperty: #highlightedMorph ifAbsent: []. + self removeProperty: #highlightedMorph. + + ((model okToChange not + or: [clickedMorph isNil]) + or: [clickedMorph ~~ highlightedMorph]) ifTrue: [ + highlightedMorph ifNotNil: [:m | m highlightForMouseDown: false]. + ^ self]. + + ((autoDeselect isNil or: [autoDeselect]) and: [clickedMorph == selectedMorph]) - mouseUp: event - | aMorph | - aMorph := self itemFromPoint: event position. - aMorph ifNil: [^self]. - aMorph highlightedForMouseDown ifFalse: [^self]. - aMorph highlightForMouseDown: false. - model okToChange ifFalse: [^self]. - "No change if model is locked" - ((autoDeselect isNil or: [autoDeselect]) and: [aMorph == selectedMorph]) ifTrue: [self setSelectedMorph: nil] + ifFalse: [self setSelectedMorph: clickedMorph]. + + highlightedMorph highlightForMouseDown: false. - ifFalse: [self setSelectedMorph: aMorph]. event hand newKeyboardFocus: self. + Cursor normal show.! - Cursor normal show! From Marcel.Taeumel at hpi.de Wed May 27 12:00:14 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Wed May 27 12:18:31 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: <1432544265553-4828430.post@n4.nabble.com> References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> <1432046950982-4827405.post@n4.nabble.com> <1432230303599-4827933.post@n4.nabble.com> <1432544265553-4828430.post@n4.nabble.com> Message-ID: <1432728014434-4828887.post@n4.nabble.com> Fixed: http://forum.world.st/The-Trunk-Morphic-mt-985-mcz-td4828886.html Note that you cannot monitor #contents in the ClockMorph because the object itself (the string morph) is replaced each second. That's why the #assert statement is very important. ;-) You may have just observed a bug I want to avoid by using this assert statement. :-) We have to find a better way to create that context menu. Maybe just copy the code from the Inspector. Best, Marcel -- View this message in context: http://forum.world.st/BUG-ObjectExplorer-menu-tp4827121p4828887.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From karlramberg at gmail.com Wed May 27 13:01:58 2015 From: karlramberg at gmail.com (karl ramberg) Date: Wed May 27 13:02:03 2015 Subject: [squeak-dev] Re: [BUG] ObjectExplorer menu In-Reply-To: <1432728014434-4828887.post@n4.nabble.com> References: <1432025619698-4827264.post@n4.nabble.com> <1432044573534-4827381.post@n4.nabble.com> <1432046950982-4827405.post@n4.nabble.com> <1432230303599-4827933.post@n4.nabble.com> <1432544265553-4828430.post@n4.nabble.com> <1432728014434-4828887.post@n4.nabble.com> Message-ID: Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: bug.png Type: image/png Size: 2723 bytes Desc: not available Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150527/ddd67f78/bug.png From leves at elte.hu Wed May 27 17:22:19 2015 From: leves at elte.hu (Levente Uzonyi) Date: Wed May 27 17:22:23 2015 Subject: [squeak-dev] Re: [Vm-dev] SqueakSSL + SAN certificates In-Reply-To: <7C590A46-B996-4BEA-AED8-AF6BA23EC80A@hartl.name> References: <7810ABD8-2D02-4FDB-AE17-9BC14A0E07A5@hartl.name> <7C590A46-B996-4BEA-AED8-AF6BA23EC80A@hartl.name> Message-ID: I thought you wanted to access the parsed data, which is not easily accessible. It's possible to export the certificate in some form (PEM or DER), but then you'd have to write a parser for that in Smalltalk. Levente On Wed, 27 May 2015, Norbert Hartl wrote: > > I don't understand. You are returning a field of the cert so you are parsing it somehow natively. Where is the difficulty just to return to whole binary certificate data? > > Norbert > > >> Am 27.05.2015 um 03:23 schrieb Levente Uzonyi : >> >> If it were possible, then there would be no need to add this. >> >> Levente >> >> On Wed, 27 May 2015, Norbert Hartl wrote: >> >>> >>> Sounds great! Is it possible to access to whole certificate data as well? >>> >>> Norbert >>> >>>> Am 26.05.2015 um 23:55 schrieb Levente Uzonyi : >>>> >>>> Hi All, >>>> >>>> I've implemented support for reading the domain names from the certificate's SAN extension[1] in SqueakSSL. >>>> The image side code is in the Inbox[2]. It is backwards compatible -- everything works as before without the VM changes. >>>> I've also uploaded the modified files[3][4] for the unix platform, and a diff[5] (which somehow doesn't include the changes of the .h file). >>>> >>>> The VM support code for other platforms are to be done. >>>> >>>> These changes fix the failing SqueakSSL test in the Trunk, so I suggest including the .mcz file in the 4.6 release. >>>> >>>> Levente >>>> >>>> [1] https://en.wikipedia.org/wiki/SubjectAltName >>>> [2] http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html >>>> [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h >>>> [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c >>>> [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt >>> >>> > > From commits at source.squeak.org Wed May 27 21:55:05 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Wed May 27 21:55:07 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150527215505.32445.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008706.html Name: Morphic-mt.985 Ancestors: Morphic-mt.984 Fixes a bug with the selection highlight in ObjectExplorer (and all other tools that use a tree widget). See: http://forum.world.st/BUG-ObjectExplorer-menu-td4827121.html ============================================= From lewis at mail.msen.com Wed May 27 23:58:22 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Wed May 27 23:58:26 2015 Subject: [squeak-dev] SqueakSSL + SAN certificates In-Reply-To: References: Message-ID: <20150527235822.GA29366@shell.msen.com> Is there any reason *not* to move SqueakSSL-Core-ul.30 from inbox to trunk? I know that we are finalizing a release, and also that there has been some follow up discussion about parsing certificates in the image, but SqueakSSL-Core-ul.30 seems like a harmless and beneficial update. So unless there are objections, I would vote to move it to trunk now. Dave On Tue, May 26, 2015 at 11:55:42PM +0200, Levente Uzonyi wrote: > Hi All, > > I've implemented support for reading the domain names from the > certificate's SAN extension[1] in SqueakSSL. > The image side code is in the Inbox[2]. It is backwards compatible -- > everything works as before without the VM changes. > I've also uploaded the modified files[3][4] for the unix platform, and a > diff[5] (which somehow doesn't include the changes of the .h file). > > The VM support code for other platforms are to be done. > > These changes fix the failing SqueakSSL test in the Trunk, so I suggest > including the .mcz file in the 4.6 release. > > Levente > > [1] https://en.wikipedia.org/wiki/SubjectAltName > [2] > http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html > [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h > [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c > [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt From commits at source.squeak.org Thu May 28 03:34:30 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 28 03:34:31 2015 Subject: [squeak-dev] The Trunk: Kernel-cmm.925.mcz Message-ID: Chris Muller uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-cmm.925.mcz ==================== Summary ==================== Name: Kernel-cmm.925 Author: cmm Time: 27 May 2015, 10:33:50.392 pm UUID: 088a1f16-41e4-414a-aedf-2e02fc7c51ba Ancestors: Kernel-mt.924 Fix an error in an error-handler. Any Exception can and must be able to #printVerboseOn:, not just Errors. =============== Diff against Kernel-mt.924 =============== Item was removed: - ----- Method: Error>>printVerboseOn: (in category 'printing') ----- - printVerboseOn: aStream - aStream - nextPutAll: 'vvvvvvvvvvvvvvvvvv ' , self description , ' vvvvvvvvvvvvvvvvvv' ; - cr ; - nextPutAll: 'The time is ', DateAndTime now asString ; - cr. - "Allow applications to optionally print extra details without overriding a base package." - (self respondsTo: #printDetailsOn:) ifTrue: [ self printDetailsOn: aStream ]. - aStream - nextPutAll: self signalerContext longStack ; - cr ; - nextPutAll: '^^^^^^^^^^^^^^^^^^ ' , self description , ' ^^^^^^^^^^^^^^^^^^' ; - cr ; - flush! Item was added: + ----- Method: Exception>>printVerboseOn: (in category 'printing') ----- + printVerboseOn: aStream + aStream + nextPutAll: 'vvvvvvvvvvvvvvvvvv ' , self description , ' vvvvvvvvvvvvvvvvvv' ; + cr ; + nextPutAll: 'The time is ', DateAndTime now asString ; + cr. + "Allow applications to optionally print extra details without overriding a base package." + (self respondsTo: #printDetailsOn:) ifTrue: [ self printDetailsOn: aStream ]. + aStream + nextPutAll: self signalerContext longStack ; + cr ; + nextPutAll: '^^^^^^^^^^^^^^^^^^ ' , self description , ' ^^^^^^^^^^^^^^^^^^' ; + cr ; + flush! From Das.Linux at gmx.de Thu May 28 11:33:22 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 28 11:33:26 2015 Subject: [squeak-dev] Error when saving class comments In-Reply-To: <14b70917a78.b68beb5184864.4169092147674391231@zoho.com> References: <06A635A5-9F71-4BD2-B401-30C4C979BB14@gmail.com> <14b70917a78.b68beb5184864.4169092147674391231@zoho.com> Message-ID: Hi all, What's the sentiment on putting this into 4.6/5.0? I think its a deal-breaker for a lot of ubuntu users if this is not working? Best regards -Tobias On 09.02.2015, at 23:59, gettimothy wrote: > This is could be the WriteStream>>nextChunkPut:aString "bug" > > At the end of that method, put a > > self flush. > > > I just tested on a fresh Squeak4.6 image and that fix fixed the error for me. > > > cheers. > > tty. > > > > ---- On Mon, 09 Feb 2015 09:55:06 -0500 Eliot Miranda wrote ---- > Hi Fabian, > > what are the permissions on the changes file? What happens when you save a method? > > Eliot (phone) > > On Feb 9, 2015, at 5:41 AM, Fabian Windheuser wrote: > > > Hello, > > Whenever I try to modify and save a class comment I get the following error: > > "Error: RemoteString past end of file" (see the attachment for the error trace). > > > > My changes are not getting saved and the file seems to get corrupted. I am no longer able to reopen this class comment because it always throws the same error. > > I tried restarting my image and using new unmodified .image and .changes files however the error still occurred. > > > > I am running Squeak 4.5 with update number #13702 on a 64bit Arch Linux distribution. > > > > Best regards, > > Fabian > > > > > > > > > > > > From Marcel.Taeumel at hpi.de Thu May 28 11:15:46 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 28 11:34:10 2015 Subject: [squeak-dev] Re: The Trunk: Kernel-cmm.925.mcz In-Reply-To: References: Message-ID: <1432811746695-4829037.post@n4.nabble.com> While you're at it: Could you add an empty #printDetailsOn: and remove this #respondsTo: call? :) Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Kernel-cmm-925-mcz-tp4828975p4829037.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Das.Linux at gmx.de Thu May 28 11:36:19 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 28 11:36:24 2015 Subject: [Vm-dev] [squeak-dev] Bug whith contextOn:do: In-Reply-To: References: <85F38DF9-1002-49A4-B11B-0DF96E0A7E76@gmx.de> Message-ID: <9ADF4F8E-D965-4676-A719-E76D6E952EEE@gmx.de> Hi all Picking up an old discussion, I'd like to include both of Eliot fixes regarding contextOn:do: and ensure into trunk before release. Any vetoes? Best regards -Tobias On 31.03.2015, at 23:10, Eliot Miranda wrote: > Hi Tobias, > > first let me sympathize. This is such horrible code :-(. Ovr the years, getting this code to work with Cog's context-to-stack-mapping machinery has given me headaches :-). > > > On Tue, Mar 31, 2015 at 9:01 AM, Tobias Pape wrote: > Hey fellow Squeakers > > [Attention: low level lengthy stuff] > > I today encountered a strange behavior. > When running the Startup code, somewhen ContextPart>>#complete is called, > which, in the process issues #contextOn:do:, which subsequently somewhere interanlly > does a jump: > > contextOn: exceptionClass do: block > "Create an #on:do: context that is ready to return from executing its receiver" > > | ctxt chain | > ctxt := thisContext. > [chain := thisContext sender cut: ctxt. ctxt jump] on: exceptionClass do: block. > "jump above will resume here without unwinding chain" > ^ chain > > The idea is that we end up right before '^ chain' as the comment indicates. > so what happens is that ctxt is the context of #contextOn:do: itself and it gets > send #jump in the closure. > > Jump now does the following: > > jump > "Abandon thisContext and resume self instead (using the same current process). You may want to save thisContext's sender before calling this so you can jump back to it. > Self MUST BE a top context (ie. a suspended context or a abandoned context that was jumped out of). A top context already has its return value on its stack (see Interpreter>>primitiveSuspend and other suspending primitives). > thisContext's sender is converted to a top context (by pushing a nil return value on its stack) so it can be jump back to." > > | top | > "Make abandoned context a top context (has return value (nil)) so it can be jumped back to" > thisContext sender push: nil. > > "Pop self return value then return it to self (since we jump to self by returning to it)" > stackp = 0 ifTrue: [self stepToSendOrReturn]. > stackp = 0 ifTrue: [self push: nil]. "must be quick return self/constant" > top := self pop. > thisContext privSender: self. > ^ top > > So. bytecode for #contextOn:do: is: > > 29 <8A 01> push: (Array new: 1) > 31 <6B> popIntoTemp: 3 > 32 <89> pushThisContext: > 33 <6A> popIntoTemp: 2 > 34 <12> pushTemp: 2 > 35 <13> pushTemp: 3 > 36 <8F 20 00 0A> closureNumCopied: 2 numArgs: 0 bytes 40 to 49 > 40 <89> pushThisContext: > 41 send: sender > 42 <10> pushTemp: 0 > 43 send: cut: > 44 <8E 00 01> popIntoTemp: 0 inVectorAt: 1 > 47 <10> pushTemp: 0 > 48 send: jump > 49 <7D> blockReturn > 50 <10> pushTemp: 0 > 51 <11> pushTemp: 1 > 52 send: on:do: > 53 <87> pop > 54 <8C 00 03> pushTemp: 0 inVectorAt: 3 > 57 <7C> returnTop > > > The jump lands right at 53 and does a pop. > HOWEVER, at this point the stack of this context is empty and the pop actually pops the 3rd temp > from the temps that 'just happens' to be right under the stack. This should be fatal. > HOWEVER again, Squeak actually does not pop but only decrement the SP so the temp access still > works(this _could_ be fine but some implementations (Eg, RSqueak) tried to separate temps and > stack; which is not possible currently). > > What could be the problem here? > - are the 'stackp = 0'-checks in #jump wrong and they actually should check for the actual stack depth _after_ temps? > > It does look like it. I would have expected this to be more correct: > > jump > "Abandon thisContext and resume self instead (using the same current process). > You may want to save thisContext's sender before calling this so you can jump back to it. > Self MUST BE a top context (ie. a suspended context or a abandoned context that was jumped > out of). A top context already has its return value on its stack (see Interpreter>>primitiveSuspend > and other suspending primitives). thisContext's sender is converted to a top context (by pushing a > nil return value on its stack) so it can be jump back to." > > | top | > "Make abandoned context a top context (has return value (nil)) so it can be jumped back to" > thisContext sender push: nil. > > "Pop self return value then return it to self (since we jump to self by returning to it)" > stackp <= self numTemps ifTrue: [self stepToSendOrReturn]. > (stackp <= self numTemps > and: [self willJustPop]) ifTrue: [self push: nil]. "must be quick return self/constant" > > top := self pop. > thisContext privSender: self. > ^top > > - should we put in a "sacrificial anode" in #contextOn:do: so that the pop does not pop the empty stack? (like this: > > contextOn: exceptionClass do: block > "Create an #on:do: context that is ready to return from executing its receiver" > > | ctxt chain | > ctxt := thisContext. > [chain := thisContext sender cut: ctxt. > ctxt push: nil. "sacrifical anode" > ctxt jump > ] on: exceptionClass do: block. > "jump above will resume here without unwinding chain" > ^ chain > > That looks right. Once the on:do: is sent the thisContext of contextOn:do:'s stack contains only exceptionClass, block, context and the indirection vector containing chain. So it is in the stack = self numTemps case. > > > - Or is there an even better way? > > I'm not sure the other ways are any better. The way to transfer to a context without disturbing its stack is to do a process switch. So you do something equivalent to > > jump > "Abandon thisContext and resume self instead (using the same current process)." > > | process semaphore | > process := Processor activeProcess. > semaphore := Semaphore new. > > [process suspendedContext unwindTo: self. > process suspendedContext: self. > semaphore signal] fork. > > semaphore wait > > This way no bizarre stack manipulations are going on, and no return value is pushed, because there isn't a return. One may get away with: > > jump > "Abandon thisContext and resume self instead (using the same current process)." > > [| process | > process := Processor activeProcess. > process suspendedContext unwindTo: self. > process suspendedContext: self] fork. > > Processor yield > > I'd be interested in your experience using either of these. One of the advantages the process switch versions have is in not updating the receiving context sp there's a chance the context-to-stack mapping machinery won't flush the context to the heap. In the end it might actually be faster. > -- > best, > Eliot From lewis at mail.msen.com Thu May 28 12:19:13 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Thu May 28 12:19:15 2015 Subject: [squeak-dev] Error when saving class comments In-Reply-To: References: <06A635A5-9F71-4BD2-B401-30C4C979BB14@gmail.com> <14b70917a78.b68beb5184864.4169092147674391231@zoho.com> Message-ID: <20150528121913.GA41121@shell.msen.com> On Thu, May 28, 2015 at 01:33:22PM +0200, Tobias Pape wrote: > Hi all, > > > What's the sentiment on putting this into 4.6/5.0? > I think its a deal-breaker for a lot of ubuntu users if > this is not working? > > Best regards > -Tobias -1 I can't recall the details, but adding #flush was a workaround, and the real problem was fixed elsewhere. The problem no longer exists in trunk. Dave > > > On 09.02.2015, at 23:59, gettimothy wrote: > > > This is could be the WriteStream>>nextChunkPut:aString "bug" > > > > At the end of that method, put a > > > > self flush. > > > > > > I just tested on a fresh Squeak4.6 image and that fix fixed the error for me. > > > > > > cheers. > > > > tty. > > > > > > > > ---- On Mon, 09 Feb 2015 09:55:06 -0500 Eliot Miranda wrote ---- > > Hi Fabian, > > > > what are the permissions on the changes file? What happens when you save a method? > > > > Eliot (phone) > > > > On Feb 9, 2015, at 5:41 AM, Fabian Windheuser wrote: > > > > > Hello, > > > Whenever I try to modify and save a class comment I get the following error: > > > "Error: RemoteString past end of file" (see the attachment for the error trace). > > > > > > My changes are not getting saved and the file seems to get corrupted. I am no longer able to reopen this class comment because it always throws the same error. > > > I tried restarting my image and using new unmodified .image and .changes files however the error still occurred. > > > > > > I am running Squeak 4.5 with update number #13702 on a 64bit Arch Linux distribution. > > > > > > Best regards, > > > Fabian > > > > > > > > > > > > > > > > > > > > > From Das.Linux at gmx.de Thu May 28 12:21:36 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 28 12:21:40 2015 Subject: [squeak-dev] Error when saving class comments In-Reply-To: <20150528121913.GA41121@shell.msen.com> References: <06A635A5-9F71-4BD2-B401-30C4C979BB14@gmail.com> <14b70917a78.b68beb5184864.4169092147674391231@zoho.com> <20150528121913.GA41121@shell.msen.com> Message-ID: <78CF354C-14EE-4A88-BDB1-C8A9FD8F1C67@gmx.de> On 28.05.2015, at 14:19, David T. Lewis wrote: > On Thu, May 28, 2015 at 01:33:22PM +0200, Tobias Pape wrote: >> Hi all, >> >> >> What's the sentiment on putting this into 4.6/5.0? >> I think its a deal-breaker for a lot of ubuntu users if >> this is not working? >> >> Best regards >> -Tobias > > -1 > > I can't recall the details, but adding #flush was a workaround, and the > real problem was fixed elsewhere. The problem no longer exists in trunk. > Oh well, if it's fixed, disregard my mail. I was under the assumption that it does _not_ yet work? Best regards -Tobias > Dave > >> >> >> On 09.02.2015, at 23:59, gettimothy wrote: >> >>> This is could be the WriteStream>>nextChunkPut:aString "bug" >>> >>> At the end of that method, put a >>> >>> self flush. >>> >>> >>> I just tested on a fresh Squeak4.6 image and that fix fixed the error for me. >>> >>> >>> cheers. >>> >>> tty. >>> >>> >>> >>> ---- On Mon, 09 Feb 2015 09:55:06 -0500 Eliot Miranda wrote ---- >>> Hi Fabian, >>> >>> what are the permissions on the changes file? What happens when you save a method? >>> >>> Eliot (phone) >>> >>> On Feb 9, 2015, at 5:41 AM, Fabian Windheuser wrote: >>> >>>> Hello, >>>> Whenever I try to modify and save a class comment I get the following error: >>>> "Error: RemoteString past end of file" (see the attachment for the error trace). >>>> >>>> My changes are not getting saved and the file seems to get corrupted. I am no longer able to reopen this class comment because it always throws the same error. >>>> I tried restarting my image and using new unmodified .image and .changes files however the error still occurred. >>>> >>>> I am running Squeak 4.5 with update number #13702 on a 64bit Arch Linux distribution. >>>> >>>> Best regards, >>>> Fabian >>>> >>>> >>>> From Das.Linux at gmx.de Thu May 28 12:29:04 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 28 12:29:08 2015 Subject: [squeak-dev] SqueakSSL + SAN certificates In-Reply-To: <20150527235822.GA29366@shell.msen.com> References: <20150527235822.GA29366@shell.msen.com> Message-ID: On 28.05.2015, at 01:58, David T. Lewis wrote: > Is there any reason *not* to move SqueakSSL-Core-ul.30 from inbox to > trunk? I know that we are finalizing a release, and also that there > has been some follow up discussion about parsing certificates in the > image, but SqueakSSL-Core-ul.30 seems like a harmless and beneficial > update. So unless there are objections, I would vote to move it to > trunk now. > Yes, the code does not handle non-SAN-aware plugin-versions. We have no code for OSX/Windows yet and no VM ships with a compatible plugin whatsoever. I'd like to postpone this one until we have a) covered all 3 platforms and b) have at least one binary somewhere. Best regards -Tobias > Dave > > > On Tue, May 26, 2015 at 11:55:42PM +0200, Levente Uzonyi wrote: >> Hi All, >> >> I've implemented support for reading the domain names from the >> certificate's SAN extension[1] in SqueakSSL. >> The image side code is in the Inbox[2]. It is backwards compatible -- >> everything works as before without the VM changes. >> I've also uploaded the modified files[3][4] for the unix platform, and a >> diff[5] (which somehow doesn't include the changes of the .h file). >> >> The VM support code for other platforms are to be done. >> >> These changes fix the failing SqueakSSL test in the Trunk, so I suggest >> including the .mcz file in the 4.6 release. >> >> Levente >> >> [1] https://en.wikipedia.org/wiki/SubjectAltName >> [2] >> http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html >> [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h >> [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c >> [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt From karlramberg at gmail.com Thu May 28 14:11:57 2015 From: karlramberg at gmail.com (karl ramberg) Date: Thu May 28 14:12:00 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: <555B3885.8070006@zogotounga.net> References: <1431317046736-4825620.post@n4.nabble.com> <1432038685392-4827343.post@n4.nabble.com> <555B3885.8070006@zogotounga.net> Message-ID: St?phane Rollandins fix should be in the release image. That bug is really annoying Karl On Tue, May 19, 2015 at 3:20 PM, St?phane Rollandin wrote: > It seems that "Auto Enclose" is not honored correctly. It is disabled in my >> image but still seems to be enabled. :-( >> >> Try typing "()" then move the cursor between the parentheses and type the >> closing one again. You will not end up with to closing ones... >> > > Yes, I noticed that also, and it bothered me enough that I fixed it by > modifying TextEditor>> #dispatchOnKeyboardEvent: as follow: > > ---------------------------------------------- > > dispatchOnKeyboardEvent: aKeyboardEvent > "Carry out the action associated with this character, if any. > Type-ahead is passed so some routines can flush or use it." > | honorCommandKeys openers closers result typedChar | > ((typedChar := aKeyboardEvent keyCharacter) == Character cr and: [ > morph acceptOnCR ]) ifTrue: > [ self closeTypeIn. > ^ true ]. > self clearParens. > aKeyboardEvent keyValue = 13 ifTrue: > [ aKeyboardEvent controlKeyPressed ifTrue: [ ^ self > normalCharacter: aKeyboardEvent ]. > aKeyboardEvent shiftPressed ifTrue: [ ^ self lf: > aKeyboardEvent ]. > aKeyboardEvent commandKeyPressed ifTrue: [ ^ self crlf: > aKeyboardEvent ]. > ^ self crWithIndent: aKeyboardEvent ]. > ((honorCommandKeys := Preferences cmdKeysInText) and: [ typedChar > = Character enter ]) ifTrue: [ ^ self dispatchOnEnterWith: aKeyboardEvent ]. > "Special keys overwrite crtl+key combinations - at least on > Windows. To resolve this > conflict, assume that keys other than cursor keys aren't used > together with Crtl." > ((self class specialShiftCmdKeys includes: aKeyboardEvent > keyValue) and: [ aKeyboardEvent keyValue < 27 ]) ifTrue: [ ^ aKeyboardEvent > controlKeyPressed > ifTrue: > [ self > perform: (self class > shiftCmdActions at: aKeyboardEvent keyValue + 1) > with: aKeyboardEvent ] > ifFalse: > [ self > perform: (self class cmdActions > at: aKeyboardEvent keyValue + 1) > with: aKeyboardEvent ] ]. > "backspace, and escape keys (ascii 8 and 27) are command keys" > ((honorCommandKeys and: [ aKeyboardEvent commandKeyPressed ]) or: > [ self class specialShiftCmdKeys includes: aKeyboardEvent keyValue ]) > ifTrue: [ ^ aKeyboardEvent shiftPressed > ifTrue: > [ self > perform: (self class > shiftCmdActions at: aKeyboardEvent keyValue + 1) > with: aKeyboardEvent ] > ifFalse: > [ self > perform: (self class cmdActions > at: aKeyboardEvent keyValue + 1) > with: aKeyboardEvent ] ]. > "the control key can be used to invoke shift-cmd shortcuts" > (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ]) > ifTrue: [ ^ self > perform: (self class shiftCmdActions at: > aKeyboardEvent keyValue + 1) > with: aKeyboardEvent ]. > openers := '([{'. > closers := ')]}'. > (closers includes: typedChar) > ifTrue: > [ self blinkPrevParen: typedChar. > (self class autoEnclose and: [self > nextNonwhitespaceCharacter = typedChar]) > ifTrue: > [ self moveCursor: [ : position | > position + 1 ] forward: true select: false. > ^ false ] > ifFalse: [ result := self normalCharacter: > aKeyboardEvent ] ] > ifFalse: [ result := self normalCharacter: aKeyboardEvent > ]. > (self class autoEnclose and: [ openers includes: typedChar ]) > ifTrue: > [ self > addString: (closers at: (openers indexOf: > typedChar)) asString ; > insertTypeAhead ; > > moveCursor: > [ : position | position - 1 ] > forward: false > select: false ]. > ^ result > > > ---------------------------------------------- > > It looks like a correct fix to me. > > Best, > > Stef > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150528/e8147dca/attachment.htm From commits at source.squeak.org Thu May 28 14:12:34 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 28 14:12:35 2015 Subject: [squeak-dev] The Inbox: Kernel.spur-kfr.925.mcz Message-ID: A new version of Kernel was added to project The Inbox: http://source.squeak.org/inbox/Kernel.spur-kfr.925.mcz ==================== Summary ==================== Name: Kernel.spur-kfr.925 Author: kfr Time: 28 May 2015, 4:03:42.244 pm UUID: 676ddbca-830f-5147-b17a-b72e499aa3eb Ancestors: Kernel.spur-eem.913, Kernel.spur-topa.920, Kernel.spur-ul.906, Kernel.spur-eem.886, Kernel.spur-mt.924 Cancelling saving a project need something like this to not get stuck with countless pre debug windows =============== Diff against Kernel.spur-eem.913 =============== Item was changed: ----- Method: ContextPart>>runUntilErrorOrReturnFrom: (in category 'controlling') ----- runUntilErrorOrReturnFrom: aSender "ASSUMES aSender is a sender of self. Execute self's stack until aSender returns or an unhandled exception is raised. Return a pair containing the new top context and a possibly nil exception. The exception is not nil if it was raised before aSender returned and it was not handled. The exception is returned rather than openning the debugger, giving the caller the choice of how to handle it." "Self is run by jumping directly to it (the active process abandons thisContext and executes self). However, before jumping to self we insert an ensure block under aSender that jumps back to thisContext when evaluated. We also insert an exception handler under aSender that jumps back to thisContext when an unhandled exception is raised. In either case, the inserted ensure and exception handler are removed once control jumps back to thisContext." | error ctxt here topContext | here := thisContext. "Insert ensure and exception handler contexts under aSender" error := nil. ctxt := aSender insertSender: (ContextPart contextOn: UnhandledError do: [:ex | error ifNil: [ error := ex exception. topContext := thisContext. ex resumeUnchecked: here jump] ifNotNil: [ex pass] ]). ctxt := ctxt insertSender: (ContextPart contextEnsure: [error ifNil: [ topContext := thisContext. here jump] ]). self jump. "Control jumps to self" "Control resumes here once above ensure block or exception handler is executed" ^ error ifNil: [ "No error was raised, remove ensure context by stepping until popped" + [ctxt isDead] whileFalse: [topContext ifNotNil:[ topContext := topContext stepToCallee]]. - [ctxt isDead] whileFalse: [topContext := topContext stepToCallee]. {topContext. nil} ] ifNotNil: [ "Error was raised, remove inserted above contexts then return signaler context" aSender terminateTo: ctxt sender. "remove above ensure and handler contexts" {topContext. error} ]. ! Item was changed: + ----- Method: InstructionClient>>callPrimitive: (in category 'instruction decoding') ----- - ----- Method: InstructionClient>>callPrimitive: (in category '*Scorch') ----- callPrimitive: pimIndex "V3PlusClosures: 139 10001011 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) NewsqueakV4: 249 11111001 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256) SistaV1: 248 11111000 iiiiiiii mjjjjjjj Call Primitive #iiiiiiii + ( jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution."! From leves at elte.hu Thu May 28 14:34:55 2015 From: leves at elte.hu (Levente Uzonyi) Date: Thu May 28 14:35:02 2015 Subject: [squeak-dev] SqueakSSL + SAN certificates In-Reply-To: References: <20150527235822.GA29366@shell.msen.com> Message-ID: On Thu, 28 May 2015, Tobias Pape wrote: > > On 28.05.2015, at 01:58, David T. Lewis wrote: > >> Is there any reason *not* to move SqueakSSL-Core-ul.30 from inbox to >> trunk? I know that we are finalizing a release, and also that there >> has been some follow up discussion about parsing certificates in the >> image, but SqueakSSL-Core-ul.30 seems like a harmless and beneficial >> update. So unless there are objections, I would vote to move it to >> trunk now. >> > > Yes, the code does not handle non-SAN-aware plugin-versions. "The image side code is in the Inbox[2]. It is backwards compatible -- everything works as before without the VM changes." Did you experience any problems with backwards compatibility? Levente > We have no code for OSX/Windows yet and no VM ships with > a compatible plugin whatsoever. I'd like to postpone this one until > we have > a) covered all 3 platforms and > b) have at least one binary somewhere. > > Best regards > -Tobias > >> Dave >> >> >> On Tue, May 26, 2015 at 11:55:42PM +0200, Levente Uzonyi wrote: >>> Hi All, >>> >>> I've implemented support for reading the domain names from the >>> certificate's SAN extension[1] in SqueakSSL. >>> The image side code is in the Inbox[2]. It is backwards compatible -- >>> everything works as before without the VM changes. >>> I've also uploaded the modified files[3][4] for the unix platform, and a >>> diff[5] (which somehow doesn't include the changes of the .h file). >>> >>> The VM support code for other platforms are to be done. >>> >>> These changes fix the failing SqueakSSL test in the Trunk, so I suggest >>> including the .mcz file in the 4.6 release. >>> >>> Levente >>> >>> [1] https://en.wikipedia.org/wiki/SubjectAltName >>> [2] >>> http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html >>> [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h >>> [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c >>> [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt > > > > From Das.Linux at gmx.de Thu May 28 14:50:01 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Thu May 28 14:50:04 2015 Subject: [squeak-dev] SqueakSSL + SAN certificates In-Reply-To: References: <20150527235822.GA29366@shell.msen.com> Message-ID: <5253DBB7-2FDF-47F4-B431-3E59B698E41E@gmx.de> On 28.05.2015, at 16:34, Levente Uzonyi wrote: > On Thu, 28 May 2015, Tobias Pape wrote: > >> >> On 28.05.2015, at 01:58, David T. Lewis wrote: >> >>> Is there any reason *not* to move SqueakSSL-Core-ul.30 from inbox to >>> trunk? I know that we are finalizing a release, and also that there >>> has been some follow up discussion about parsing certificates in the >>> image, but SqueakSSL-Core-ul.30 seems like a harmless and beneficial >>> update. So unless there are objections, I would vote to move it to >>> trunk now. >>> >> >> Yes, the code does not handle non-SAN-aware plugin-versions. > > "The image side code is in the Inbox[2]. It is backwards compatible -- everything works as before without the VM changes." > > Did you experience any problems with backwards compatibility? Actually I only read the code. Sorry. I just saw that subjectAltNameDNS will hand through the primitiveFailed if used on a plugin that does not have SQSSL_PROP_SUBJECTALTNAMEDNS. Verifcation is not fully done yet on OSX anyway? And the more I read the C code and the Smalltalk code, I'd really like to not change the Smalltalk side. Here's why: The point of both SNI and sAN are that you want that the server name you called to is validated. One is on the protocol level one is on the ceritificate level. Both Windows Schannel and OS X Secure Transport abstract that away. And I think it is easily possible to do that with openssl as well by just traversing all sANs and setting the same validity information as with SNI. That way we also don't need to pass a specially formatted string to the image. I find that odd, a bit. On a different note, providing Certificate information to the image is probably still a good idea but I don't think we should do sAN that way. Thoughts? Best regards -Tobias > > Levente > >> We have no code for OSX/Windows yet and no VM ships with >> a compatible plugin whatsoever. I'd like to postpone this one until >> we have >> a) covered all 3 platforms and >> b) have at least one binary somewhere. >> >> Best regards >> -Tobias >> >>> Dave >>> >>> >>> On Tue, May 26, 2015 at 11:55:42PM +0200, Levente Uzonyi wrote: >>>> Hi All, >>>> >>>> I've implemented support for reading the domain names from the >>>> certificate's SAN extension[1] in SqueakSSL. >>>> The image side code is in the Inbox[2]. It is backwards compatible -- >>>> everything works as before without the VM changes. >>>> I've also uploaded the modified files[3][4] for the unix platform, and a >>>> diff[5] (which somehow doesn't include the changes of the .h file). >>>> >>>> The VM support code for other platforms are to be done. >>>> >>>> These changes fix the failing SqueakSSL test in the Trunk, so I suggest >>>> including the .mcz file in the 4.6 release. >>>> >>>> Levente >>>> >>>> [1] https://en.wikipedia.org/wiki/SubjectAltName >>>> [2] >>>> http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html >>>> [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h >>>> [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c >>>> [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt From brasspen at gmail.com Thu May 28 15:03:09 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Thu May 28 15:03:14 2015 Subject: [squeak-dev] [OT} About a Web Page Framework For Cuis Message-ID: I bought an old book on OS X Carbon once. It lead me down the rabbit hole of code archaeology, where you try to go back in time, collect things, and build something that was. You?re always missing something. Looking at GreenNeon on Cuis is sort of like that. Set the time machine for 2013. tl;dr - You need a working WebClient for Cuis. The one I used [1] is not available. I?ve added one from garduino [2] that informs the Test Runner it has 50 failed tests. The image I built is long gone. Here?s is the latest Cuis (4.2, released 2013) with garduino?s Networking code, his WebClient, and my GreenNeon. [3] There are a few useful snippets in the Workspace. I think that if WebClient worked, then so would GreenNeon. But I?m not about to try and debug WebClient on Cuis. Your best bet might be to contact David Graham for his WebClient code. Chris [1] https://github.com/davidgraham/Cuis-WebClient [2] https://github.com/garduino/Cuis-Smalltalk-WebClient [3] https://www.dropbox.com/s/c0js490trp1pu4m/Cuis-WebClient-GreenNeon.zip?dl=0 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150528/65dbdaf5/attachment.htm From asqueaker at gmail.com Thu May 28 15:29:11 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu May 28 15:29:15 2015 Subject: [squeak-dev] Re: The Trunk: Kernel-cmm.925.mcz In-Reply-To: <1432811746695-4829037.post@n4.nabble.com> References: <1432811746695-4829037.post@n4.nabble.com> Message-ID: No, because as the comment says, I want to be able to implement my own Exception>>#printDetailsOn: without overriding a base package. On Thu, May 28, 2015 at 6:15 AM, marcel.taeumel wrote: > While you're at it: Could you add an empty #printDetailsOn: and remove this > #respondsTo: call? :) > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Kernel-cmm-925-mcz-tp4828975p4829037.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From asqueaker at gmail.com Thu May 28 15:45:36 2015 From: asqueaker at gmail.com (Chris Muller) Date: Thu May 28 15:45:39 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: References: <1431317046736-4825620.post@n4.nabble.com> <1432038685392-4827343.post@n4.nabble.com> <555B3885.8070006@zogotounga.net> Message-ID: Yes, I've cut'n'pasted his method out of his email, and it works, but does anyone (Marcel?) know why the cursor disappears after typing ()? I haven't had a chance to figure that out yet, I want to fix both.. On Thu, May 28, 2015 at 9:11 AM, karl ramberg wrote: > St?phane Rollandins fix should be in the release image. > That bug is really annoying > > Karl > > On Tue, May 19, 2015 at 3:20 PM, St?phane Rollandin < > lecteur@zogotounga.net> wrote: > >> It seems that "Auto Enclose" is not honored correctly. It is disabled in >>> my >>> image but still seems to be enabled. :-( >>> >>> Try typing "()" then move the cursor between the parentheses and type the >>> closing one again. You will not end up with to closing ones... >>> >> >> Yes, I noticed that also, and it bothered me enough that I fixed it by >> modifying TextEditor>> #dispatchOnKeyboardEvent: as follow: >> >> ---------------------------------------------- >> >> dispatchOnKeyboardEvent: aKeyboardEvent >> "Carry out the action associated with this character, if any. >> Type-ahead is passed so some routines can flush or use it." >> | honorCommandKeys openers closers result typedChar | >> ((typedChar := aKeyboardEvent keyCharacter) == Character cr and: >> [ morph acceptOnCR ]) ifTrue: >> [ self closeTypeIn. >> ^ true ]. >> self clearParens. >> aKeyboardEvent keyValue = 13 ifTrue: >> [ aKeyboardEvent controlKeyPressed ifTrue: [ ^ self >> normalCharacter: aKeyboardEvent ]. >> aKeyboardEvent shiftPressed ifTrue: [ ^ self lf: >> aKeyboardEvent ]. >> aKeyboardEvent commandKeyPressed ifTrue: [ ^ self crlf: >> aKeyboardEvent ]. >> ^ self crWithIndent: aKeyboardEvent ]. >> ((honorCommandKeys := Preferences cmdKeysInText) and: [ typedChar >> = Character enter ]) ifTrue: [ ^ self dispatchOnEnterWith: aKeyboardEvent ]. >> "Special keys overwrite crtl+key combinations - at least on >> Windows. To resolve this >> conflict, assume that keys other than cursor keys aren't used >> together with Crtl." >> ((self class specialShiftCmdKeys includes: aKeyboardEvent >> keyValue) and: [ aKeyboardEvent keyValue < 27 ]) ifTrue: [ ^ aKeyboardEvent >> controlKeyPressed >> ifTrue: >> [ self >> perform: (self class >> shiftCmdActions at: aKeyboardEvent keyValue + 1) >> with: aKeyboardEvent ] >> ifFalse: >> [ self >> perform: (self class cmdActions >> at: aKeyboardEvent keyValue + 1) >> with: aKeyboardEvent ] ]. >> "backspace, and escape keys (ascii 8 and 27) are command keys" >> ((honorCommandKeys and: [ aKeyboardEvent commandKeyPressed ]) or: >> [ self class specialShiftCmdKeys includes: aKeyboardEvent keyValue ]) >> ifTrue: [ ^ aKeyboardEvent shiftPressed >> ifTrue: >> [ self >> perform: (self class >> shiftCmdActions at: aKeyboardEvent keyValue + 1) >> with: aKeyboardEvent ] >> ifFalse: >> [ self >> perform: (self class cmdActions >> at: aKeyboardEvent keyValue + 1) >> with: aKeyboardEvent ] ]. >> "the control key can be used to invoke shift-cmd shortcuts" >> (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ]) >> ifTrue: [ ^ self >> perform: (self class shiftCmdActions at: >> aKeyboardEvent keyValue + 1) >> with: aKeyboardEvent ]. >> openers := '([{'. >> closers := ')]}'. >> (closers includes: typedChar) >> ifTrue: >> [ self blinkPrevParen: typedChar. >> (self class autoEnclose and: [self >> nextNonwhitespaceCharacter = typedChar]) >> ifTrue: >> [ self moveCursor: [ : position | >> position + 1 ] forward: true select: false. >> ^ false ] >> ifFalse: [ result := self >> normalCharacter: aKeyboardEvent ] ] >> ifFalse: [ result := self normalCharacter: aKeyboardEvent >> ]. >> (self class autoEnclose and: [ openers includes: typedChar ]) >> ifTrue: >> [ self >> addString: (closers at: (openers indexOf: >> typedChar)) asString ; >> insertTypeAhead ; >> >> moveCursor: >> [ : position | position - 1 ] >> forward: false >> select: false ]. >> ^ result >> >> >> ---------------------------------------------- >> >> It looks like a correct fix to me. >> >> Best, >> >> Stef >> >> >> >> > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150528/53962b0f/attachment.htm From Marcel.Taeumel at hpi.de Thu May 28 15:35:08 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 28 15:53:31 2015 Subject: [squeak-dev] Re: The Trunk: Kernel-cmm.925.mcz In-Reply-To: References: <1432811746695-4829037.post@n4.nabble.com> Message-ID: <1432827308722-4829095.post@n4.nabble.com> Having to read this comment and the whole implementation to get to know about this extension point is *very* bad style. ;-) You're right, we would have to change the comment, too. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Kernel-cmm-925-mcz-tp4828975p4829095.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From Marcel.Taeumel at hpi.de Thu May 28 15:35:30 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Thu May 28 15:53:52 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: References: <1431317046736-4825620.post@n4.nabble.com> <1432038685392-4827343.post@n4.nabble.com> <555B3885.8070006@zogotounga.net> Message-ID: <1432827330094-4829096.post@n4.nabble.com> I can take a look at it. Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-977-mcz-tp4825591p4829096.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From ma.chris.m at gmail.com Thu May 28 20:14:04 2015 From: ma.chris.m at gmail.com (Chris Muller) Date: Thu May 28 20:14:08 2015 Subject: [squeak-dev] mc history is back up Message-ID: In case you tried to use the mc history function the lsat few days and it failed, its now back up. From garduino at gmail.com Thu May 28 21:43:15 2015 From: garduino at gmail.com (=?UTF-8?Q?Germ=C3=A1n_Arduino?=) Date: Thu May 28 21:43:18 2015 Subject: [squeak-dev] [OT} About a Web Page Framework For Cuis In-Reply-To: References: Message-ID: Hi Chris: Thanks you for your effort! In the last times, WebClient was cleaned and renamed by David [1] and now is part of the core packages of Cuis [2]. I should delete my own WC repo. I will try (when time permit) check your image and try to package GreenNeon in Cuis format. Thanks again! Germ?n. [1] http://forum.world.st/ANN-Cuis-HTTP-Cuis-WebClient-replacement-td4815990.html [2] https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev/tree/master/Packages 2015-05-28 12:03 GMT-03:00 Chris Cunnington : > I bought an old book on OS X Carbon once. It lead me down the rabbit hole > of code archaeology, where you try to go back in time, collect things, and > build something that was. You?re always missing something. Looking at > GreenNeon on Cuis is sort of like that. Set the time machine for 2013. > > tl;dr - You need a working WebClient for Cuis. The one I used [1] is not > available. I?ve added one from garduino [2] that informs the Test Runner it > has 50 failed tests. > > The image I built is long gone. Here?s is the latest Cuis (4.2, released > 2013) with garduino?s Networking code, his WebClient, and my GreenNeon. [3] > There are a few useful snippets in the Workspace. I think that if WebClient > worked, then so would GreenNeon. But I?m not about to try and debug > WebClient on Cuis. Your best bet might be to contact David Graham for his > WebClient code. > Chris > > > [1] https://github.com/davidgraham/Cuis-WebClient > [2] https://github.com/garduino/Cuis-Smalltalk-WebClient > [3] > https://www.dropbox.com/s/c0js490trp1pu4m/Cuis-WebClient-GreenNeon.zip?dl=0 > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150528/f5fa8f01/attachment-0001.htm From commits at source.squeak.org Thu May 28 21:55:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Thu May 28 21:55:12 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150528215511.11322.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008707.html Name: Kernel-cmm.925 Ancestors: Kernel-mt.924 Fix an error in an error-handler. Any Exception can and must be able to #printVerboseOn:, not just Errors. ============================================= From brasspen at gmail.com Thu May 28 23:16:12 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Thu May 28 23:16:16 2015 Subject: [squeak-dev] [OT] About a Web Page Framework For Cuis Message-ID: <544CCE65-CD50-4D9D-BE5F-71C517153480@gmail.com> OK. Looks like I was using the wrong package for WebClient. I?ll install the correct package and start again. Chris >Hi Chris: >Thanks you for your effort! >In the last times, WebClient was cleaned and renamed by David [1] and now >is part of the core packages of Cuis [2]. >I should delete my own WC repo. >I will try (when time permit) check your image and try to package GreenNeon >in Cuis format. >Thanks again! >Germ?n. [1] http://forum.world.st/ANN-Cuis-HTTP-Cuis-WebClient-replacement-td4815990.html [2] https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev/tree/master/Packages 2015-05-28 12:03 GMT-03:00 Chris Cunnington >: > I bought an old book on OS X Carbon once. It lead me down the rabbit hole > of code archaeology, where you try to go back in time, collect things, and > build something that was. You?re always missing something. Looking at > GreenNeon on Cuis is sort of like that. Set the time machine for 2013. > > tl;dr - You need a working WebClient for Cuis. The one I used [1] is not > available. I?ve added one from garduino [2] that informs the Test Runner it > has 50 failed tests. > > The image I built is long gone. Here?s is the latest Cuis (4.2, released > 2013) with garduino?s Networking code, his WebClient, and my GreenNeon. [3] > There are a few useful snippets in the Workspace. I think that if WebClient > worked, then so would GreenNeon. But I?m not about to try and debug > WebClient on Cuis. Your best bet might be to contact David Graham for his > WebClient code. > Chris > > > [1] https://github.com/davidgraham/Cuis-WebClient > [2] https://github.com/garduino/Cuis-Smalltalk-WebClient > [3] > https://www.dropbox.com/s/c0js490trp1pu4m/Cuis-WebClient-GreenNeon.zip?dl=0 > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150528/0d25a08e/attachment.htm From lewis at mail.msen.com Fri May 29 00:05:46 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri May 29 00:05:49 2015 Subject: [squeak-dev] mc history is back up In-Reply-To: References: Message-ID: <20150529000546.GB48114@shell.msen.com> On Thu, May 28, 2015 at 03:14:04PM -0500, Chris Muller wrote: > In case you tried to use the mc history function the lsat few days and > it failed, its now back up. Thanks! I have not had occasion to use it in the last few days, but it is a really useful thing to have when you need it. Dave From commits at source.squeak.org Fri May 29 02:12:38 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 02:12:42 2015 Subject: [squeak-dev] The Trunk: System-cmm.738.mcz Message-ID: Chris Muller uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-cmm.738.mcz ==================== Summary ==================== Name: System-cmm.738 Author: cmm Time: 28 May 2015, 9:11:50.464 pm UUID: 261f1783-9b35-4a2b-a386-fa429b57ebab Ancestors: System-ul.737 Fix #run: leaving headless image stuck because there was a MNU or Halt. =============== Diff against System-ul.737 =============== Item was changed: ----- Method: SmalltalkImage>>run: (in category 'command line') ----- run: aBlock [ [ (aBlock numArgs = 1 and: [ self arguments size > 1 ]) ifTrue: [ "Allow a large, variable number of arguments to be passed as an Array to aBlock." aBlock value: self arguments ] ifFalse: [ aBlock valueWithEnoughArguments: self arguments ] ] on: ProgressInitiationException do: + [ : pie | "Don't want to log these notifications." - [ : pie | "Don't want to log this notification." pie defaultAction ] ] on: Notification , Warning do: [ : noti | FileStream stdout nextPutAll: DateAndTime now asString ; space ; nextPutAll: noti description ; cr. noti resume ] on: SyntaxErrorNotification do: [ : err | FileStream stdout nextPutAll: err errorCode ; cr; flush. self isHeadless ifTrue: [ self snapshot: false andQuit: true ] ifFalse: [ err pass ] ] + on: Error, MessageNotUnderstood, Halt - on: Error do: [ : err | err printVerboseOn: FileStream stderr. FileStream stderr flush. self isHeadless ifTrue: [ self snapshot: false andQuit: true ] ifFalse: [ err pass ] ]! From pbpublist at gmail.com Fri May 29 02:17:48 2015 From: pbpublist at gmail.com (Phil (list)) Date: Fri May 29 02:17:31 2015 Subject: [squeak-dev] [OT] About a Web Page Framework For Cuis In-Reply-To: <544CCE65-CD50-4D9D-BE5F-71C517153480@gmail.com> References: <544CCE65-CD50-4D9D-BE5F-71C517153480@gmail.com> Message-ID: <1432865868.2280.3.camel@gmail.com> On Thu, 2015-05-28 at 19:16 -0400, Chris Cunnington wrote: > OK. Looks like I was using the wrong package for WebClient. > I?ll install the correct package and start again. > Why not just create a repo for the packages on github? > Chris > > > >Hi Chris: > > >Thanks you for your effort! > > >In the last times, WebClient was cleaned and renamed by David [1] and now > >is part of the core packages of Cuis [2]. > > >I should delete my own WC repo. > > >I will try (when time permit) check your image and try to package GreenNeon > >in Cuis format. > > >Thanks again! > > >Germ?n. > > > > > [1] > http://forum.world.st/ANN-Cuis-HTTP-Cuis-WebClient-replacement-td4815990.html > [2] > https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev/tree/master/Packages > > 2015-05-28 12:03 GMT-03:00 Chris Cunnington : > > > I bought an old book on OS X Carbon once. It lead me down the rabbit hole > > of code archaeology, where you try to go back in time, collect things, and > > build something that was. You?re always missing something. Looking at > > GreenNeon on Cuis is sort of like that. Set the time machine for 2013. > > > > tl;dr - You need a working WebClient for Cuis. The one I used [1] is not > > available. I?ve added one from garduino [2] that informs the Test Runner it > > has 50 failed tests. > > > > The image I built is long gone. Here?s is the latest Cuis (4.2, released > > 2013) with garduino?s Networking code, his WebClient, and my GreenNeon. [3] > > There are a few useful snippets in the Workspace. I think that if WebClient > > worked, then so would GreenNeon. But I?m not about to try and debug > > WebClient on Cuis. Your best bet might be to contact David Graham for his > > WebClient code. > > Chris > > > > > > [1] https://github.com/davidgraham/Cuis-WebClient > > [2] https://github.com/garduino/Cuis-Smalltalk-WebClient > > [3] > > https://www.dropbox.com/s/c0js490trp1pu4m/Cuis-WebClient-GreenNeon.zip?dl=0 > > > > > > > > > > From Marcel.Taeumel at hpi.de Fri May 29 06:51:30 2015 From: Marcel.Taeumel at hpi.de (marcel.taeumel) Date: Fri May 29 07:09:58 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: References: <1431317046736-4825620.post@n4.nabble.com> <1432038685392-4827343.post@n4.nabble.com> <555B3885.8070006@zogotounga.net> Message-ID: <1432882290234-4829239.post@n4.nabble.com> Hmm... I cannot reproduce this bug. Looks fine here. Can you tell about your preferences in your working image? Best, Marcel -- View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-977-mcz-tp4825591p4829239.html Sent from the Squeak - Dev mailing list archive at Nabble.com. From edgardec2005 at gmail.com Fri May 29 09:59:01 2015 From: edgardec2005 at gmail.com (Edgar J. De Cleene) Date: Fri May 29 09:59:12 2015 Subject: [squeak-dev] [OT} About a Web Page Framework For Cuis In-Reply-To: Message-ID: On 5/28/15, 12:03 PM, "Chris Cunnington" wrote: > I bought an old book on OS X Carbon once. It lead me down the rabbit hole of > code archaeology, where you try to go back in time, collect things, and build > something that was. You?re always missing something. Looking at GreenNeon on > Cuis is sort of like that. Set the time machine for 2013. > > tl;dr - You need a working WebClient for Cuis. The one I used [1] is not > available. I?ve added one from garduino [2] that informs the Test Runner it > has 50 failed tests. > > The image I built is long gone. Here?s is the latest Cuis (4.2, released 2013) > with garduino?s Networking code, his WebClient, and my GreenNeon. [3] There > are a few useful snippets in the Workspace. I think that if WebClient worked, > then so would GreenNeon. But I?m not about to try and debug WebClient on Cuis. > Your best bet might be to contact David Graham for his WebClient code. > Chris > > > [1] https://github.com/davidgraham/Cuis-WebClient > [2] https://github.com/garduino/Cuis-Smalltalk-WebClient > [3] > https://www.dropbox.com/s/c0js490trp1pu4m/Cuis-WebClient-GreenNeon.zip?dl=0 Veery thanks and we heavily welcome you in Cuis list if you wish Edgar -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150529/add8c123/attachment.htm From brasspen at gmail.com Fri May 29 17:23:07 2015 From: brasspen at gmail.com (Chris Cunnington) Date: Fri May 29 17:23:14 2015 Subject: [squeak-dev] GreenNeon On Cuis In-Reply-To: References: <20140501080531.493624077a7c3f67688650f9@whidbey.com> <555A8705.5080502@jvuletich.org> <5567082D.2090107@jvuletich.org> Message-ID: Here is the image for Cuis. [1] A script for Squeak [2]. I?ll blog details next week. Have a nice weekend, Chris [1] https://www.dropbox.com/s/1j738w8ye5ujhok/Cuis-GreenNeon.zip?dl=0 [2] Installer ss project: 'WebClient'; install: 'WebClient-Core'; install: 'WebClient-HTTP'; install: 'WebClient-Help'. Installer ss3 project: 'Oakville'; install: 'GreenNeon?. GNHelloWorld startOn: 9944 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150529/6fa2ed1c/attachment.htm From garduino at gmail.com Fri May 29 18:12:38 2015 From: garduino at gmail.com (=?UTF-8?Q?Germ=C3=A1n_Arduino?=) Date: Fri May 29 18:12:41 2015 Subject: [squeak-dev] GreenNeon On Cuis In-Reply-To: References: <20140501080531.493624077a7c3f67688650f9@whidbey.com> <555A8705.5080502@jvuletich.org> <5567082D.2090107@jvuletich.org> Message-ID: Hi Chris: Excellent, thanks! I sent a mail early today saying: -------------------------------------------------------------------------------------------- I did a quick packaging (as a Cuis package) of GreenNeon and added the requirements to make it load in a current Cuis 4.2 image (2343). It load ok but with several undeclared that seems to exist also in the original image. By other hand I fixed quickly some names as the current HTTP (ex WebClient) package requires, but the localhost:8821 with the example seems not work yet. The snippets of the workspace should be now (for adhere to the new class names in HTTP package): resp := HTTPClient httpGet: 'http://www.squeak.org'. resp content. HTTPServer exampleBrowse. GNHelloWorld startOn: 8821 As Phil said, the way to go is create a GitHub repo for GreenNeon, but I let it to Chris, the original author of the package. HTH -------------------------------------------------------------------------------------------- But is awaiting moderator approval (for the size of the attached pck). >From this new version that is in your image, would be interesting to create a GitHub repo and a Cuis package for GreenNeon. Let me know if I can help with some of these duties. Cheers. 2015-05-29 14:23 GMT-03:00 Chris Cunnington : > Here is the image for Cuis. [1] A script for Squeak [2]. > I?ll blog details next week. > > Have a nice weekend, > Chris > > > > [1] https://www.dropbox.com/s/1j738w8ye5ujhok/Cuis-GreenNeon.zip?dl=0 > > > [2] > > Installer ss project: 'WebClient'; > install: 'WebClient-Core'; > install: 'WebClient-HTTP'; > install: 'WebClient-Help'. > Installer ss3 project: 'Oakville'; > install: 'GreenNeon?. > > > GNHelloWorld startOn: 9944 > > > > -- Saludos / Regards, Germ?n Arduino www.arduinosoftware.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150529/11316f5a/attachment.htm From asqueaker at gmail.com Fri May 29 18:27:38 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri May 29 18:27:40 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: <1432882290234-4829239.post@n4.nabble.com> References: <1431317046736-4825620.post@n4.nabble.com> <1432038685392-4827343.post@n4.nabble.com> <555B3885.8070006@zogotounga.net> <1432882290234-4829239.post@n4.nabble.com> Message-ID: In updated TrunkImage, turn on Auto Enclose. Then type () in a workspace. For me, the cursor disappears. On Fri, May 29, 2015 at 1:51 AM, marcel.taeumel wrote: > Hmm... I cannot reproduce this bug. Looks fine here. Can you tell about your > preferences in your working image? > > Best, > Marcel > > > > -- > View this message in context: http://forum.world.st/The-Trunk-Morphic-cmm-977-mcz-tp4825591p4829239.html > Sent from the Squeak - Dev mailing list archive at Nabble.com. > From leves at elte.hu Fri May 29 18:38:33 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri May 29 18:38:39 2015 Subject: [squeak-dev] SqueakSSL + SAN certificates In-Reply-To: <5253DBB7-2FDF-47F4-B431-3E59B698E41E@gmx.de> References: <20150527235822.GA29366@shell.msen.com> <5253DBB7-2FDF-47F4-B431-3E59B698E41E@gmx.de> Message-ID: On Thu, 28 May 2015, Tobias Pape wrote: > > On 28.05.2015, at 16:34, Levente Uzonyi wrote: > >> On Thu, 28 May 2015, Tobias Pape wrote: >> >>> >>> On 28.05.2015, at 01:58, David T. Lewis wrote: >>> >>>> Is there any reason *not* to move SqueakSSL-Core-ul.30 from inbox to >>>> trunk? I know that we are finalizing a release, and also that there >>>> has been some follow up discussion about parsing certificates in the >>>> image, but SqueakSSL-Core-ul.30 seems like a harmless and beneficial >>>> update. So unless there are objections, I would vote to move it to >>>> trunk now. >>>> >>> >>> Yes, the code does not handle non-SAN-aware plugin-versions. >> >> "The image side code is in the Inbox[2]. It is backwards compatible -- everything works as before without the VM changes." >> >> Did you experience any problems with backwards compatibility? > > Actually I only read the code. Sorry. > I just saw that subjectAltNameDNS will hand through the primitiveFailed > if used on a plugin that does not have SQSSL_PROP_SUBJECTALTNAMEDNS. > Verifcation is not fully done yet on OSX anyway? > > > And the more I read the C code and the Smalltalk code, I'd really like to > not change the Smalltalk side. If you want the plugin to verify that the certificate matches the name of the server, then the Smalltalk code will have to be changed too. > > Here's why: > The point of both SNI and sAN are that you want that the server name you > called to is validated. One is on the protocol level one is on the ceritificate SNI allows one to name the server, and this allows the plugin to verify that the certificate matches the server name. > level. Both Windows Schannel and OS X Secure Transport abstract that away. > And I think it is easily possible to do that with openssl as well by > just traversing all sANs and setting the same validity information as with > SNI. OpenSSL (prior v1.1.0) doesn't support the verification of the server name out of the box[1]. On Win32 it's turned off with the ISC_REQ_MANUAL_CRED_VALIDATION flag. The same applies to the OSX version: /* Disable cert verification since we do that ourselves */ status = SSLSetEnableCertVerify(ssl->ctx, false); This means that no variants of the plugin verify the server name, it's only done in Smalltalk. On Win32 and OSX it can be implemented easily. It's possible to do it with OpenSSL too, but it's a bit more complicated. > That way we also don't need to pass a specially formatted string to > the image. I find that odd, a bit. It may be odd, but this is an essential part of the verification process[2]. > > On a different note, providing Certificate information to the image is probably > still a good idea but I don't think we should do sAN that way. How much information would you like to pass to the image? Just the server's certificate, or the whole certificate chain? What about the overhead of the certificate serialization? Would you just ignore it, or make the certificate extraction optional? Levente [1] https://wiki.openssl.org/index.php/SSL/TLS_Client#Certificate_Names [2] https://wiki.openssl.org/index.php/SSL/TLS_Client#Verification > > Thoughts? > > Best regards > -Tobias > > > >> >> Levente >> >>> We have no code for OSX/Windows yet and no VM ships with >>> a compatible plugin whatsoever. I'd like to postpone this one until >>> we have >>> a) covered all 3 platforms and >>> b) have at least one binary somewhere. >>> >>> Best regards >>> -Tobias >>> >>>> Dave >>>> >>>> >>>> On Tue, May 26, 2015 at 11:55:42PM +0200, Levente Uzonyi wrote: >>>>> Hi All, >>>>> >>>>> I've implemented support for reading the domain names from the >>>>> certificate's SAN extension[1] in SqueakSSL. >>>>> The image side code is in the Inbox[2]. It is backwards compatible -- >>>>> everything works as before without the VM changes. >>>>> I've also uploaded the modified files[3][4] for the unix platform, and a >>>>> diff[5] (which somehow doesn't include the changes of the .h file). >>>>> >>>>> The VM support code for other platforms are to be done. >>>>> >>>>> These changes fix the failing SqueakSSL test in the Trunk, so I suggest >>>>> including the .mcz file in the 4.6 release. >>>>> >>>>> Levente >>>>> >>>>> [1] https://en.wikipedia.org/wiki/SubjectAltName >>>>> [2] >>>>> http://lists.squeakfoundation.org/pipermail/squeak-dev/2015-May/184581.html >>>>> [3] http://leves.web.elte.hu/squeak/SqueakSSL/SqueakSSL.h >>>>> [4] http://leves.web.elte.hu/squeak/SqueakSSL/sqUnixOpenSSL.c >>>>> [5] http://leves.web.elte.hu/squeak/SqueakSSL/diff.txt > > > > From leves at elte.hu Fri May 29 18:45:44 2015 From: leves at elte.hu (Levente Uzonyi) Date: Fri May 29 18:45:49 2015 Subject: [squeak-dev] Re: The Trunk: Morphic-cmm.977.mcz In-Reply-To: References: <1431317046736-4825620.post@n4.nabble.com> <1432038685392-4827343.post@n4.nabble.com> <555B3885.8070006@zogotounga.net> Message-ID: The code is also broken, when Auto Enclose is enabled. The cause of the problem is that code ignores the number of whitespace characters. If you open a workspace and type the following line: ] "five spaces and a closing bracket" and move the cursor to the beginning of the line, then you have to press ] seven times to make another closing bracket appear. Levente On Thu, 28 May 2015, karl ramberg wrote: > > St?phane Rollandins fix should be in the release image. > > That bug is really annoying > > Karl > > On Tue, May 19, 2015 at 3:20 PM, St?phane Rollandin wrote: > It seems that "Auto Enclose" is not honored correctly. It is disabled in my > image but still seems to be enabled. :-( > > Try typing "()" then move the cursor between the parentheses and type the > closing one again. You will not end up with to closing ones... > > > Yes, I noticed that also, and it bothered me enough that I fixed it by modifying TextEditor>> #dispatchOnKeyboardEvent: as follow: > > ---------------------------------------------- > > dispatchOnKeyboardEvent: aKeyboardEvent > ? ? ? ? "Carry out the action associated with this character, if any. Type-ahead is passed so some routines can flush or use it." > ? ? ? ? | honorCommandKeys openers closers result typedChar | > ? ? ? ? ((typedChar := aKeyboardEvent keyCharacter) == Character cr and: [ morph acceptOnCR ]) ifTrue: > ? ? ? ? ? ? ? ? [ self closeTypeIn. > ? ? ? ? ? ? ? ? ^ true ]. > ? ? ? ? self clearParens. > ? ? ? ? aKeyboardEvent keyValue = 13 ifTrue: > ? ? ? ? ? ? ? ? [ aKeyboardEvent controlKeyPressed ifTrue: [ ^ self normalCharacter: aKeyboardEvent ]. > ? ? ? ? ? ? ? ? aKeyboardEvent shiftPressed ifTrue: [ ^ self lf: aKeyboardEvent ]. > ? ? ? ? ? ? ? ? aKeyboardEvent commandKeyPressed ifTrue: [ ^ self crlf: aKeyboardEvent ]. > ? ? ? ? ? ? ? ? ^ self crWithIndent: aKeyboardEvent ]. > ? ? ? ? ((honorCommandKeys := Preferences cmdKeysInText) and: [ typedChar = Character enter ]) ifTrue: [ ^ self dispatchOnEnterWith: aKeyboardEvent ]. > ? ? ? ? "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this > ? ? ? ? conflict, assume that keys other than cursor keys aren't used together with Crtl." > ? ? ? ? ((self class specialShiftCmdKeys includes: aKeyboardEvent keyValue) and: [ aKeyboardEvent keyValue < 27 ]) ifTrue: [ ^ aKeyboardEvent controlKeyPressed > ? ? ? ? ? ? ? ? ? ? ? ? ifTrue: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [ self > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? with: aKeyboardEvent ] > ? ? ? ? ? ? ? ? ? ? ? ? ifFalse: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [ self > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? with: aKeyboardEvent ] ]. > ? ? ? ? "backspace, and escape keys (ascii 8 and 27) are command keys" > ? ? ? ? ((honorCommandKeys and: [ aKeyboardEvent commandKeyPressed ]) or: [ self class specialShiftCmdKeys includes: aKeyboardEvent keyValue ]) ifTrue: [ ^ aKeyboardEvent shiftPressed > ? ? ? ? ? ? ? ? ? ? ? ? ifTrue: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [ self > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? with: aKeyboardEvent ] > ? ? ? ? ? ? ? ? ? ? ? ? ifFalse: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [ self > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? with: aKeyboardEvent ] ]. > ? ? ? ? "the control key can be used to invoke shift-cmd shortcuts" > ? ? ? ? (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ]) ifTrue: [ ^ self > ? ? ? ? ? ? ? ? ? ? ? ? perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) > ? ? ? ? ? ? ? ? ? ? ? ? with: aKeyboardEvent ]. > ? ? ? ? openers := '([{'. > ? ? ? ? closers := ')]}'. > ? ? ? ? (closers includes: typedChar) > ? ? ? ? ? ? ? ? ifTrue: > ? ? ? ? ? ? ? ? ? ? ? ? [ self blinkPrevParen: typedChar. > ? ? ? ? ? ? ? ? ? ? ? ? (self class autoEnclose and: [self nextNonwhitespaceCharacter = typedChar]) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ifTrue: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [ self moveCursor: [ : position | position + 1 ] forward: true select: false. > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ^ false ] > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ifFalse: [ result := self normalCharacter: aKeyboardEvent ] ] > ? ? ? ? ? ? ? ? ifFalse: [ result := self normalCharacter: aKeyboardEvent ]. > ? ? ? ? (self class autoEnclose and: [ openers includes: typedChar ]) ifTrue: > ? ? ? ? ? ? ? ? [ self > ? ? ? ? ? ? ? ? ? ? ? ? ?addString: (closers at: (openers indexOf: typedChar)) asString ; > ? ? ? ? ? ? ? ? ? ? ? ? ?insertTypeAhead ; > ? ? ? ? ? ? ? ? ? ? ? ? > ? ? ? ? ? ? ? ? ? ? ? ? moveCursor: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [ : position | position - 1 ] > ? ? ? ? ? ? ? ? ? ? ? ? forward: false > ? ? ? ? ? ? ? ? ? ? ? ? select: false ]. > ? ? ? ? ^ result > > > ---------------------------------------------- > > It looks like a correct fix to me. > > Best, > > Stef > > > > > > From commits at source.squeak.org Fri May 29 18:59:29 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 18:59:33 2015 Subject: [squeak-dev] The Trunk: Compiler-eem.298.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-eem.298.mcz ==================== Summary ==================== Name: Compiler-eem.298 Author: eem Time: 29 May 2015, 11:59:13.77 am UUID: b06cc000-4a40-45cd-a0b2-a2d1c0309e39 Ancestors: Compiler-cmm.297 Provide multiple-bytecode-sets aware support for markerOrNil =============== Diff against Compiler-cmm.297 =============== Item was added: + ----- Method: BytecodeEncoder class>>markerOrNilFor: (in category 'compiled method support') ----- + markerOrNilFor: aMethod + "If aMethod is a marker method, answer the symbol used to mark it. Otherwise + answer nil. What is a marker method? It is method with body like + 'self subclassResponsibility' or '^ self subclassResponsibility' + used to indicate ('mark') a special property. + + Marker methods compile to two bytecode forms, this: + self + send: + pop + returnSelf + or this: + self + send: + returnTop" + ^self subclassResponsibility! Item was added: + ----- Method: EncoderForV3 class>>markerOrNilFor: (in category 'compiled method support') ----- + markerOrNilFor: aMethod + "If aMethod is a marker method, answer the symbol used to mark it. Otherwise + answer nil. What is a marker method? It is method with body like + 'self subclassResponsibility' or '^ self subclassResponsibility' + used to indicate ('mark') a special property. + + Marker methods compile to two bytecode forms, this: + self + send: + pop + returnSelf + or this: + self + send: + returnTop" + | e | + ^(((e := aMethod endPC) = 19 or: [e = 20]) + and: [aMethod numLiterals = 3 + and: [(aMethod at: 17) = 16r70 "push self" + and: [(aMethod at: 18) = 16rD0]]]) "send " + ifTrue: [aMethod literalAt: 1]! From commits at source.squeak.org Fri May 29 19:03:12 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 19:03:15 2015 Subject: [squeak-dev] The Trunk: Kernel-eem.926.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.926.mcz ==================== Summary ==================== Name: Kernel-eem.926 Author: eem Time: 29 May 2015, 12:02:32.361 pm UUID: b5d090c6-115c-427d-92ca-0e02afa2908d Ancestors: Kernel-cmm.925 Make markerOrNil multiple-bytecode-sets aware =============== Diff against Kernel-cmm.925 =============== Item was changed: ----- Method: CompiledMethod>>markerOrNil (in category 'private') ----- markerOrNil "If I am a marker method, answer the symbol used to mark me. Otherwise + answer nil. What is a marker method? It is method with body like - answer nil. - - What is a marker method? It is method with body like 'self subclassResponsibility' or '^ self subclassResponsibility' + used to indicate ('mark') a special property." - used to indicate ('mark') a special property. + ^self encoderClass markerOrNilFor: self! - Marker methods compile to bytecode like: - - 9 <70> self - 10 send: - 11 <87> pop - 12 <78> returnSelf - - for the first form, or - - 9 <70> self - 10 send: - 11 <7C> returnTop - - for the second form." - - | e | - ((e := self endPC) = 19 or: [e = 20]) ifFalse: [^ nil]. - (self numLiterals = 3) ifFalse:[^ nil]. - (self at: 17) = 16r70 ifFalse:[^ nil]. "push self" - (self at: 18) = 16rD0 ifFalse:[^ nil]. "send " - "If we reach this point, we have a marker method that sends self " - ^ self literalAt: 1 - ! Item was added: + ----- Method: InstructionPrinter>>callPrimitive: (in category 'instruction decoding') ----- + callPrimitive: index + "Print the callPrimitive bytecode." + + self print: 'callPrimitive: ' , index printString! From Das.Linux at gmx.de Fri May 29 19:25:58 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Fri May 29 19:26:03 2015 Subject: [squeak-dev] MCMUpdater and CI Message-ID: <03D231FC-84D8-4F13-B684-368C4C5C060C@gmx.de> Hey We have changed the way the MCMUpdater works, I recall. Probably this has broken the CI Build: http://build.squeak.org/job/SqueakTrunk/1493/console Who can take a look at it? Best regards -Tobias From lewis at mail.msen.com Fri May 29 19:44:57 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Fri May 29 19:45:00 2015 Subject: [squeak-dev] MCMUpdater and CI In-Reply-To: <03D231FC-84D8-4F13-B684-368C4C5C060C@gmx.de> References: <03D231FC-84D8-4F13-B684-368C4C5C060C@gmx.de> Message-ID: <27225.136.2.1.105.1432928697.squirrel@webmail.msen.com> I made the changes in MCMUpdater, so I am probably the cause of this problem in the build. I will look at it this weekend and fix it as soon as possible. Dave > Hey > > We have changed the way the MCMUpdater works, I recall. > Probably this has broken the CI Build: > http://build.squeak.org/job/SqueakTrunk/1493/console > > Who can take a look at it? > > Best regards > -Tobias > From commits at source.squeak.org Fri May 29 21:08:40 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 21:08:44 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.986.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.986.mcz ==================== Summary ==================== Name: Morphic-cmm.986 Author: cmm Time: 29 May 2015, 4:07:48.693 pm UUID: a448eb5a-ab1f-4acc-9c76-ebdaac144d58 Ancestors: Morphic-cmm.984, Morphic-mt.985 - Merged cmm.984. - Auto Enclose fixes. =============== Diff against Morphic-mt.985 =============== Item was changed: ----- Method: Morph>>handlesMouseMove: (in category 'event handling') ----- handlesMouseMove: anEvent "Do I want to receive mouseMove: when the hand passes over the receiver? Rules say that by default a morph gets #mouseMove iff * the hand is not dragging anything, + and some button is down, + and the receiver is the current mouse focus." + self eventHandler ifNotNil: [^ self eventHandler handlesMouseMove: anEvent]. anEvent hand hasSubmorphs ifTrue: [ ^ false ]. (anEvent anyButtonPressed and: [ anEvent hand mouseFocus == self ]) ifFalse: [ ^ false ]. ^ true! Item was added: + ----- Method: TextEditor>>autoEncloseFor: (in category 'typing support') ----- + autoEncloseFor: typedChar + "Answer whether typeChar was handled by auto-enclosure. Caller should call normalCharacter if not." + | openers closers | + openers := '([{'. + closers := ')]}'. + (closers includes: typedChar) + ifTrue: + [ | pos | + self blinkPrevParen: typedChar. + ((pos := self indexOfNextNonwhitespaceCharacter) notNil and: [ (paragraph string at: pos) = typedChar ]) + ifTrue: + [ (paragraph string at: pos) = typedChar ifTrue: + [ self + moveCursor: [ : position | position + pos - pointBlock stringIndex + 1 ] + forward: true + select: false ]. + ^ true ] + ifFalse: [ ^ false ] ]. + (self class autoEnclose and: [ openers includes: typedChar ]) ifTrue: + [ self + addString: (closers at: (openers indexOf: typedChar)) asString ; + insertTypeAhead ; + + moveCursor: [ : position | position - 1 ] + forward: false + select: false. + ^ false ]. + ^ false! Item was changed: ----- Method: TextEditor>>dispatchOnKeyboardEvent: (in category 'typing support') ----- dispatchOnKeyboardEvent: aKeyboardEvent "Carry out the action associated with this character, if any. Type-ahead is passed so some routines can flush or use it." + | honorCommandKeys typedChar | - | honorCommandKeys openers closers result typedChar | ((typedChar := aKeyboardEvent keyCharacter) == Character cr and: [ morph acceptOnCR ]) ifTrue: [ self closeTypeIn. ^ true ]. self clearParens. aKeyboardEvent keyValue = 13 ifTrue: [ aKeyboardEvent controlKeyPressed ifTrue: [ ^ self normalCharacter: aKeyboardEvent ]. aKeyboardEvent shiftPressed ifTrue: [ ^ self lf: aKeyboardEvent ]. aKeyboardEvent commandKeyPressed ifTrue: [ ^ self crlf: aKeyboardEvent ]. ^ self crWithIndent: aKeyboardEvent ]. ((honorCommandKeys := Preferences cmdKeysInText) and: [ typedChar = Character enter ]) ifTrue: [ ^ self dispatchOnEnterWith: aKeyboardEvent ]. "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this conflict, assume that keys other than cursor keys aren't used together with Crtl." ((self class specialShiftCmdKeys includes: aKeyboardEvent keyValue) and: [ aKeyboardEvent keyValue < 27 ]) ifTrue: [ ^ aKeyboardEvent controlKeyPressed ifTrue: [ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ifFalse: [ self perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ]. "backspace, and escape keys (ascii 8 and 27) are command keys" ((honorCommandKeys and: [ aKeyboardEvent commandKeyPressed ]) or: [ self class specialShiftCmdKeys includes: aKeyboardEvent keyValue ]) ifTrue: [ ^ aKeyboardEvent shiftPressed ifTrue: [ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ifFalse: [ self perform: (self class cmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ] ]. "the control key can be used to invoke shift-cmd shortcuts" (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ]) ifTrue: [ ^ self perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1) with: aKeyboardEvent ]. + self class autoEnclose + ifTrue: [ (self autoEncloseFor: typedChar) ifFalse: [ self normalCharacter: aKeyboardEvent ] ] + ifFalse: [ self normalCharacter: aKeyboardEvent ]. + ^ false! - openers := '([{'. - closers := ')]}'. - (closers includes: typedChar) - ifTrue: - [ self blinkPrevParen: typedChar. - self nextNonwhitespaceCharacter = typedChar - ifTrue: - [ self moveCursor: [ : position | position + 1 ] forward: true select: false. - ^ false ] - ifFalse: [ result := self normalCharacter: aKeyboardEvent ] ] - ifFalse: [ result := self normalCharacter: aKeyboardEvent ]. - (self class autoEnclose and: [ openers includes: typedChar ]) ifTrue: - [ self - addString: (closers at: (openers indexOf: typedChar)) asString ; - insertTypeAhead ; - - moveCursor: - [ : position | position - 1 ] - forward: false - select: false ]. - ^ result! Item was added: + ----- Method: TextEditor>>indexOfNextNonwhitespaceCharacter (in category 'private') ----- + indexOfNextNonwhitespaceCharacter + pointBlock stringIndex + to: paragraph string size + do: + [ : n | | char | (char := paragraph string at: n) isSeparator ifFalse: [ ^ n ] ]. + ^ nil! Item was removed: - ----- Method: TextEditor>>nextNonwhitespaceCharacter (in category 'private') ----- - nextNonwhitespaceCharacter - pointBlock stringIndex - to: paragraph string size - do: - [ : n | | char | (char := paragraph string at: n) isSeparator ifFalse: [ ^ char ] ]. - ^ nil! From commits at source.squeak.org Fri May 29 21:12:18 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 21:12:22 2015 Subject: [squeak-dev] The Trunk: Morphic-cmm.984.mcz Message-ID: Chris Muller uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-cmm.984.mcz ==================== Summary ==================== Name: Morphic-cmm.984 Author: cmm Time: 19 May 2015, 2:56:17.688 pm UUID: e1b37491-efb5-4415-bf9f-6f44b577daa0 Ancestors: Morphic-mt.983 Fix the ability to let Morph users set up their own EventHandler to have proper filtering of MouseMoveEvents. =============== Diff against Morphic-mt.983 =============== Item was changed: ----- Method: Morph>>handlesMouseMove: (in category 'event handling') ----- handlesMouseMove: anEvent "Do I want to receive mouseMove: when the hand passes over the receiver? Rules say that by default a morph gets #mouseMove iff * the hand is not dragging anything, + and some button is down, + and the receiver is the current mouse focus." + self eventHandler ifNotNil: [^ self eventHandler handlesMouseMove: anEvent]. anEvent hand hasSubmorphs ifTrue: [ ^ false ]. (anEvent anyButtonPressed and: [ anEvent hand mouseFocus == self ]) ifFalse: [ ^ false ]. ^ true! From commits at source.squeak.org Fri May 29 21:55:08 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 21:55:10 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150529215508.26165.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008708.html Name: System-cmm.738 Ancestors: System-ul.737 Fix #run: leaving headless image stuck because there was a MNU or Halt. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008709.html Name: Compiler-eem.298 Ancestors: Compiler-cmm.297 Provide multiple-bytecode-sets aware support for markerOrNil ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008710.html Name: Kernel-eem.926 Ancestors: Kernel-cmm.925 Make markerOrNil multiple-bytecode-sets aware ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008711.html Name: Morphic-cmm.986 Ancestors: Morphic-cmm.984, Morphic-mt.985 - Merged cmm.984. - Auto Enclose fixes. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008712.html Name: Morphic-cmm.984 Ancestors: Morphic-mt.983 Fix the ability to let Morph users set up their own EventHandler to have proper filtering of MouseMoveEvents. ============================================= From commits at source.squeak.org Fri May 29 22:25:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 22:26:01 2015 Subject: [squeak-dev] The Trunk: Compiler-eem.299.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-eem.299.mcz ==================== Summary ==================== Name: Compiler-eem.299 Author: eem Time: 29 May 2015, 3:25:41.119 pm UUID: 04451481-d898-4b03-bc51-9e28546cfb82 Ancestors: Compiler-eem.298 Provide support for a specialized pushNClosureTemps: bytecode, as included in the Sista bytecode set. =============== Diff against Compiler-eem.298 =============== Item was added: + ----- Method: BytecodeEncoder>>sizePushNClosureTemps: (in category 'opcode sizing') ----- + sizePushNClosureTemps: numTemps + ^self sizeOpcodeSelector: #genPushNClosureTemps: withArguments: {numTemps}! Item was added: + ----- Method: EncoderForV3PlusClosures>>genPushNClosureTemps: (in category 'bytecode generation') ----- + genPushNClosureTemps: numTemps + numTemps timesRepeat: [self genPushSpecialLiteral: nil]! From commits at source.squeak.org Fri May 29 22:31:58 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 22:32:02 2015 Subject: [squeak-dev] The Trunk: Compiler-eem.300.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler-eem.300.mcz ==================== Summary ==================== Name: Compiler-eem.300 Author: eem Time: 29 May 2015, 3:31:40.184 pm UUID: 538f90f4-71d3-4f00-ac34-348700471a82 Ancestors: Compiler-eem.299 Use the size/emitPushNClosureTemps: api in block generation. =============== Diff against Compiler-eem.299 =============== Item was changed: ----- Method: BlockNode>>emitCodeForEvaluatedClosureValue:encoder: (in category 'code generation (closures)') ----- emitCodeForEvaluatedClosureValue: stack encoder: encoder | position | position := stack position. stack position: arguments size + copiedValues size. + encoder genPushNClosureTemps: temporaries size. - temporaries size timesRepeat: - [NodeNil emitCodeForValue: stack encoder: encoder]. self reindexingLocalsDo: [self emitCodeForEvaluatedValue: stack encoder: encoder] encoder: encoder. self returns ifFalse: [encoder genReturnTopToCaller. pc := encoder methodStreamPosition]. stack position: position! Item was changed: ----- Method: BlockNode>>sizeCodeForEvaluatedClosureValue: (in category 'code generation (closures)') ----- sizeCodeForEvaluatedClosureValue: encoder "The closure value primitives push the arguments and the copied values. The compiler guarantees that any copied values come before all local temps. So on closure activation we only need to push nils for the remaining temporaries." + ^(encoder sizePushNClosureTemps: temporaries size) - ^temporaries size * (NodeNil sizeCodeForValue: encoder) + (self reindexingLocalsDo: [self sizeCodeForEvaluatedValue: encoder] encoder: nil "don't store temps yet") + (self returns ifTrue: [0] ifFalse: [encoder sizeReturnTopToCaller])! From commits at source.squeak.org Fri May 29 22:44:40 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 22:44:41 2015 Subject: [squeak-dev] The Trunk: ReleaseBuilder-cmm.123.mcz Message-ID: Chris Muller uploaded a new version of ReleaseBuilder to project The Trunk: http://source.squeak.org/trunk/ReleaseBuilder-cmm.123.mcz ==================== Summary ==================== Name: ReleaseBuilder-cmm.123 Author: cmm Time: 29 May 2015, 5:44:29.7 pm UUID: 7b74b571-a20e-42f7-b387-b31a7aed87e1 Ancestors: ReleaseBuilder-topa.122 - #clearPasswords was renamed to #clearCredentials. - Updated ReleaseBuilder class>>#versionString. =============== Diff against ReleaseBuilder-topa.122 =============== Item was changed: ----- Method: ReleaseBuilder class>>prepareNewBuild: (in category 'scripts') ----- prepareNewBuild: anMCRepository "ReleaseBuilderTrunk prepareNewBuild" "Prepare everything that should be done for a new image build" MCMcmUpdater updateMissingPackages: true. MCMcmUpdater enableUpdatesForAllPackages. TTCFont registerAll. RealEstateAgent standardSize: 600 @ 400. SystemVersion newVersion: self versionString. SMLoaderPlus setDefaultFilters: (OrderedCollection with: #filterSafelyAvailable). " Preferences outOfTheBox." "<-- uncomment after #defaultValueTableForCurrentRelease is fixed up." self setDisplayExtent: 800 @ 600 ; switchToNewRepository: anMCRepository ; setPreferences ; "<-- remove this after defaultValueTableForCurrentRelease is fixed up." checkForDirtyPackages ; configureDesktop. Smalltalk cleanUp: true. "Let's be explicit about clearing passwords for the publicly-consumed build." "clearPasswords is not very thorough, it should be improved." + MCHttpRepository clearCredentials. - MCHttpRepository clearPasswordsAndUsers. Utilities setAuthorInitials: String empty. Environment allInstancesDo: [ : env | env purgeUndeclared ]. Undeclared removeUnreferencedKeys. Smalltalk garbageCollect. [ self loadWellKnownPackages "<-- 4.5 is not ready for unloaded / reloaded packages" ]. Compiler recompileAll! Item was changed: ----- Method: ReleaseBuilder class>>prepareNextVersionAlpha (in category 'scripts') ----- prepareNextVersionAlpha "Prepare the first alpha image for next release." SystemVersion newVersion: ((UIManager default request: 'Please specify the name of the\new version of Squeak.' withCRs initialAnswer: SystemVersion current version) ifEmpty: [^ self inform: 'Aborted.']). MCFileBasedRepository flushAllCaches. + MCHttpRepository clearCredentials. - MCHttpRepository clearPasswords. Utilities setAuthorInitials: String empty. self switchToNewRepository: self buildRepository. Smalltalk condenseSources! Item was changed: ----- Method: ReleaseBuilder class>>versionString (in category 'private') ----- versionString + ^ 'Squeak4.6'! - ^ 'Squeak4.5'.! From commits at source.squeak.org Fri May 29 23:03:56 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:03:57 2015 Subject: [squeak-dev] The Trunk: Collections-eem.636.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections-eem.636.mcz ==================== Summary ==================== Name: Collections-eem.636 Author: eem Time: 29 May 2015, 4:03:27.101 pm UUID: 0ccecc27-ca23-41aa-be79-584dbc53e4d0 Ancestors: Collections-mt.635 findLast:startingAt: dual for findFirst:startingAt: =============== Diff against Collections-mt.635 =============== Item was added: + ----- Method: SequenceableCollection>>findLast:startingAt: (in category 'enumerating') ----- + findLast: aBlock startingAt: i + "Return the index of my last element with index >= i for which aBlock evaluates as true." + + | index | + index := self size + 1. + [(index := index - 1) >= i] whileTrue: + [(aBlock value: (self at: index)) ifTrue: [^index]]. + ^ 0! From commits at source.squeak.org Fri May 29 23:05:35 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:05:37 2015 Subject: [squeak-dev] The Trunk: Kernel-eem.927.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.927.mcz ==================== Summary ==================== Name: Kernel-eem.927 Author: eem Time: 29 May 2015, 4:04:53.411 pm UUID: b759de23-0d29-460f-94ba-69d3ee900124 Ancestors: Kernel-eem.926 Support for condensing sources and changes while preserving direct history. =============== Diff against Kernel-eem.926 =============== Item was added: + ----- Method: ClassDescription>>fileOutCategoryHistorically:on:moveSource:toFile: (in category 'fileIn/Out') ----- + fileOutCategoryHistorically: aSymbol on: aFileStream moveSource: moveSource toFile: fileIndex + "File a description of the receiver's category, aString, onto aFileStream, preserving direct + history, but excluding branches . If moveSource, is true, then set the method source pointer + to the new file position. Note when this method is called with moveSource=true, it is + condensing the sources file, and should only write one preamble per method category." + + | selectors | + aFileStream cr. + selectors := aSymbol asString = ClassOrganizer allCategory + ifTrue: [self organization allMethodSelectors] + ifFalse: [self organization listAtCategoryNamed: aSymbol]. + + selectors := selectors select: [:each | self includesLocalSelector: each]. + + "Overridden to preserve author stamps in sources file regardless." + selectors do: [:sel | + self printMethodChunkHistorically: sel + on: aFileStream + moveSource: moveSource + toFile: fileIndex]! Item was changed: ----- Method: ClassDescription>>fileOutChangedMessages:on:moveSource:toFile: (in category 'fileIn/Out') ----- fileOutChangedMessages: aSet on: aFileStream moveSource: moveSource toFile: fileIndex "File a description of the messages of this class that have been changed (i.e., are entered into the argument, aSet) onto aFileStream. If moveSource, is true, then set the method source pointer to the new file position. Note when this method is called with moveSource=true, it is condensing the .changes file, and should only write a preamble for every method." | org | (org := self organization) categories do: + [:cat | | sels | - [:cat | - | sels | sels := (org listAtCategoryNamed: cat) select: [:sel | aSet includes: sel]. + (moveSource == #historically + or: [moveSource and: [(cat beginsWith: '*') and: [cat endsWith: '-override']]]) + ifTrue: "when condensing sources/changes, preserve overridden methods" + [sels do: + [:sel | + self printMethodChunkHistorically: sel on: aFileStream + moveSource: moveSource ~~ false toFile: fileIndex]] + ifFalse: + [sels do: - (moveSource and: [(cat beginsWith: '*') and: [cat endsWith: '-override']]) - ifTrue: ["when condensing sources/changes, preserve overridden methods" - sels do: - [:sel | self printMethodChunkHistorically: sel on: aFileStream - moveSource: moveSource toFile: fileIndex]] - ifFalse: [ - sels do: [:sel | self printMethodChunk: sel withPreamble: true on: aFileStream moveSource: moveSource toFile: fileIndex]]]! Item was changed: ----- Method: ClassDescription>>fileOutOn:moveSource:toFile: (in category 'fileIn/Out') ----- fileOutOn: aFileStream moveSource: moveSource toFile: fileIndex + "File a description of the receiver on aFileStream. moveSOurce is one of + true, false or #historically. If the argument, moveSource, is not false, then + set the trailing bytes to the position of aFileStream and to fileIndex in order + to indicate where to find the source code. If moveSource == #historically, + print out each method's history, excluding branches" - "File a description of the receiver on aFileStream. If the boolean - argument, moveSource, is true, then set the trailing bytes to the position - of aFileStream and to fileIndex in order to indicate where to find the - source code." + aFileStream command: 'H3'; nextChunkPut: self definition; command: '/H3'. - aFileStream command: 'H3'. - aFileStream nextChunkPut: self definition. - aFileStream command: '/H3'. self organization putCommentOnFile: aFileStream numbered: fileIndex + moveSource: moveSource ~~ false - moveSource: moveSource forClass: self. self organization categories do: [:heading | + moveSource == #historically + ifTrue: + [self fileOutCategoryHistorically: heading + on: aFileStream + moveSource: true + toFile: fileIndex] + ifFalse: + [self fileOutCategory: heading + on: aFileStream + moveSource: moveSource + toFile: fileIndex]]! - self fileOutCategory: heading - on: aFileStream - moveSource: moveSource - toFile: fileIndex]! Item was changed: ----- Method: ClassDescription>>printMethodChunkHistorically:on:moveSource:toFile: (in category 'fileIn/Out') ----- printMethodChunkHistorically: selector on: outStream moveSource: moveSource toFile: fileIndex "Copy all source codes historically for the method associated with selector onto the + fileStream. If moveSource is true, then also set the source code pointer of the method. + N.B. fileIndex is interpreted as follows, 0 => just a fileOut; 1 => condensing sources; + 2 => condensing changes; therefore only changes on the chnages file before the last + version in the sources file are recorded." - fileStream. If moveSource true, then also set the source code pointer of the method." + | preamble method newPos category changeList prior index | - | preamble method sourceFile endPos category changeList newPos | category := self organization categoryOfElement: selector. preamble := self name , ' methodsFor: ', category asString printString. method := self methodDict at: selector. + (method filePosition = 0 + or: [method fileIndex = 0 + or: [(SourceFiles at: method fileIndex) isNil]]) + ifTrue: "no source; must decompile" + [outStream cr; nextPut: $!!; nextChunkPut: preamble; cr. + outStream nextChunkPut: method decompileString. + outStream nextChunkPut: ' '; cr] + ifFalse: + [changeList := ChangeSet directAncestryOfVersions: (ChangeSet + scanVersionsOf: method + class: self + meta: self isMeta + category: category + selector: selector). + newPos := prior := nil. + (fileIndex = 2 "condensing changes; select changes file code and find last sources file change" + and: [(index := changeList findFirst: [:chgRec| chgRec fileIndex = 1]) > 0]) ifTrue: + [prior := changeList at: index. + changeList := changeList copyFrom: 1 to: index - 1]. + changeList reverseDo: + [:chgRec| + chgRec file closed ifTrue: + [chgRec file reopen; setToEnd]. + outStream copyPreamble: preamble from: chgRec file at: chgRec position. + prior ifNotNil: + [outStream + position: outStream position - 2; + nextPutAll: ' prior: '; + print: (SourceFiles + sourcePointerFromFileIndex: prior fileIndex + andPosition: prior position); + nextPut: $!!; cr]. - ((method fileIndex = 0 - or: [(SourceFiles at: method fileIndex) == nil]) - or: [method filePosition = 0]) - ifTrue: [ - outStream cr; nextPut: $!!; nextChunkPut: preamble; cr. - outStream nextChunkPut: method decompileString. - outStream nextChunkPut: ' '; cr] - ifFalse: [ - changeList := ChangeSet - scanVersionsOf: method - class: self - meta: self isMeta - category: category - selector: selector. - newPos := nil. - sourceFile := SourceFiles at: method fileIndex. - changeList reverseDo: [ :chgRec | | prior | - chgRec fileIndex = fileIndex ifTrue: [ - outStream copyPreamble: preamble from: sourceFile at: chgRec position. - (prior := chgRec prior) ifNotNil: [ - outStream position: outStream position - 2. - outStream nextPutAll: ' prior: ', ( - prior first = method fileIndex ifFalse: [prior third] ifTrue: [ - SourceFiles - sourcePointerFromFileIndex: method fileIndex - andPosition: newPos]) printString. - outStream nextPut: $!!; cr]. "Copy the method chunk" newPos := outStream position. + outStream copyMethodChunkFrom: chgRec file at: chgRec position. + chgRec file skipSeparators. "The following chunk may have ]style[" + chgRec file peek == $] ifTrue: + [outStream cr; copyMethodChunkFrom: chgRec file]. + outStream nextChunkPut: ' '; cr. + chgRec position: newPos. + prior := chgRec]. + moveSource ifTrue: + [method setSourcePosition: newPos inFile: fileIndex]]. + ^outStream! - outStream copyMethodChunkFrom: sourceFile at: chgRec position. - sourceFile skipSeparators. "The following chunk may have ]style[" - sourceFile peek == $] ifTrue: [ - outStream cr; copyMethodChunkFrom: sourceFile]. - outStream nextChunkPut: ' '; cr]]. - moveSource ifTrue: [ - endPos := outStream position. - method checkOKToAdd: endPos - newPos at: newPos. - method setSourcePosition: newPos inFile: fileIndex]]. - ^ outStream! Item was changed: ----- Method: Metaclass>>fileOutOn:moveSource:toFile:initializing: (in category 'fileIn/Out') ----- fileOutOn: aFileStream moveSource: moveSource toFile: fileIndex initializing: aBool + super fileOutOn: aFileStream moveSource: moveSource toFile: fileIndex. + (aBool + and: [moveSource == false + and: [self methodDict includesKey: #initialize]]) ifTrue: + [aFileStream cr; cr; nextChunkPut: thisClass name , ' initialize'; cr]! - super fileOutOn: aFileStream - moveSource: moveSource - toFile: fileIndex. - (aBool and:[moveSource not and: [self methodDict includesKey: #initialize]]) ifTrue: - [aFileStream cr. - aFileStream cr. - aFileStream nextChunkPut: thisClass name , ' initialize'. - aFileStream cr]! From commits at source.squeak.org Fri May 29 23:06:43 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:06:45 2015 Subject: [squeak-dev] The Trunk: System-eem.739.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-eem.739.mcz ==================== Summary ==================== Name: System-eem.739 Author: eem Time: 29 May 2015, 4:06:02.935 pm UUID: 0b6049b8-02b1-4f6e-97eb-8776c9604f3e Ancestors: System-cmm.738 Support for condensing sources and changes while preserving direct history. =============== Diff against System-cmm.738 =============== Item was added: + ----- Method: ChangeRecord>>file (in category 'access') ----- + file + ^file! Item was added: + ----- Method: ChangeRecord>>position: (in category 'access') ----- + position: anInteger + "Set the position. Dangerous!! Used in condenseChanges implementation by a very knowledgeable client!!" + position := anInteger! Item was added: + ----- Method: ChangeSet class>>directAncestryOfVersions: (in category 'scanning') ----- + directAncestryOfVersions: changeRecords + "Take a sequence of ChangeRecords as answered by scanVersionsOf:class:meta:category:selector: + and answer a filtered subsequence consisting only of direct ancestors. For example, if the input is + eem 7/7/2009 20:06 7 July 2009 8:06 pm + eem 6/18/2009 19:21 18 June 2009 7:21 pm + eem 5/5/2009 12:16 5 May 2009 12:16 pm + eem 6/18/2009 19:19 18 June 2009 7:19 pm + eem 6/18/2009 18:57 18 June 2009 6:57 pm + eem 5/5/2009 12:16 5 May 2009 12:16 pm + eem 6/18/2009 18:17 18 June 2009 6:17 pm + eem 6/18/2009 18:14 18 June 2009 6:14 pm + eem 6/18/2009 18:06 18 June 2009 6:06 pm + eem 5/5/2009 12:16 5 May 2009 12:16 pm + eem 5/4/2009 19:19 4 May 2009 7:19 pm + the output should be + eem 7/7/2009 20:06 7 July 2009 8:06 pm + eem 6/18/2009 19:21 18 June 2009 7:21 pm + eem 5/5/2009 12:16 5 May 2009 12:16 pm + eem 5/4/2009 19:19 4 May 2009 7:19 pm" + + | filtered i last | + filtered := OrderedCollection new. + i := 1. + [i <= changeRecords size] whileTrue: + [filtered addLast: (changeRecords at: i). + last := changeRecords + findLast: [:chgRec| filtered last stamp = chgRec stamp and: [filtered last position = chgRec position]] + startingAt: i. + i := last = 0 ifTrue: [i + 1] ifFalse: [last + 1]]. + ^filtered! From commits at source.squeak.org Fri May 29 23:09:27 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:09:28 2015 Subject: [squeak-dev] The Trunk: Kernel-eem.928.mcz Message-ID: Eliot Miranda uploaded a new version of Kernel to project The Trunk: http://source.squeak.org/trunk/Kernel-eem.928.mcz ==================== Summary ==================== Name: Kernel-eem.928 Author: eem Time: 29 May 2015, 4:08:39.106 pm UUID: 42550ae5-1cf6-41e1-8e22-93b7ad2a6166 Ancestors: Kernel-eem.927 Modify condenseChanges to preserve direct method history. =============== Diff against Kernel-eem.927 =============== Item was changed: ----- Method: ClassDescription>>moveChangesTo: (in category 'fileIn/Out') ----- moveChangesTo: newFile "Used in the process of condensing changes, this message requests that the source code of all methods of the receiver that have been changed should be moved to newFile." | changes | changes := self methodDict keys select: [:sel | (self compiledMethodAt: sel) fileIndex > 1]. self fileOutChangedMessages: changes on: newFile + moveSource: #historically - moveSource: true toFile: 2! From commits at source.squeak.org Fri May 29 23:10:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:10:28 2015 Subject: [squeak-dev] The Trunk: System-eem.740.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System-eem.740.mcz ==================== Summary ==================== Name: System-eem.740 Author: eem Time: 29 May 2015, 4:09:46.189 pm UUID: 53894fe9-e3f5-44c7-b4c2-101e4d72f0d3 Ancestors: System-eem.739 Modify condensSources to preserve direct method history. =============== Diff against System-eem.739 =============== Item was changed: ----- Method: SmalltalkImage>>condenseSources (in category 'housekeeping') ----- condenseSources "Move all the changes onto a compacted sources file." "Smalltalk condenseSources" | newSourcesFile defaultDirectory newVersion currentVersion | Utilities fixUpProblemsWithAllCategory. "The above removes any concrete, spurious '-- all --' categories, which mess up the process." defaultDirectory := FileDirectory default. currentVersion := self sourceFileVersionString. newVersion := UIManager default request: 'Please designate the version\for the new source code file...' withCRs initialAnswer: currentVersion. newVersion ifEmpty: [ ^ self ]. newVersion = currentVersion ifTrue: [ ^ self error: 'The new source file must not be the same as the old.' ]. self sourceFileVersionString: newVersion. "Write all sources with fileIndex 1" newSourcesFile := defaultDirectory newFileNamed: (defaultDirectory localNameFor: self sourcesName). newSourcesFile ifNil: [ ^ self error: 'Couldn''t create source code file in\' withCRs, defaultDirectory name]. newSourcesFile header; timeStamp. 'Condensing Sources File...' displayProgressFrom: 0 to: self classNames size + self traitNames size during: [ :bar | | count | count := 0. Smalltalk allClassesAndTraitsDo: [ :classOrTrait | bar value: (count := count + 1). classOrTrait fileOutOn: newSourcesFile + moveSource: #historically - moveSource: true toFile: 1 ] ]. newSourcesFile trailer; close. "Make a new empty changes file" self closeSourceFiles. defaultDirectory rename: self changesName toBe: self changesName , '.old'. (FileStream newFileNamed: self changesName) header; timeStamp; close. self lastQuitLogPosition: 0. self setMacFileInfoOn: self changesName. self setMacFileInfoOn: newSourcesFile name. self openSourceFiles. self inform: 'Source files have been rewritten to\' withCRs, newSourcesFile name, '\Check that all is well,\and then save/quit.' withCRs! From asqueaker at gmail.com Fri May 29 23:27:25 2015 From: asqueaker at gmail.com (Chris Muller) Date: Fri May 29 23:27:29 2015 Subject: [squeak-dev] The Trunk: System-eem.740.mcz In-Reply-To: <5568f1e7.76578c0a.229b.1440SMTPIN_ADDED_MISSING@mx.google.com> References: <5568f1e7.76578c0a.229b.1440SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Thanks Eliot these features are needed for the release. On Fri, May 29, 2015 at 6:10 PM, wrote: > Eliot Miranda uploaded a new version of System to project The Trunk: > http://source.squeak.org/trunk/System-eem.740.mcz > > ==================== Summary ==================== > > Name: System-eem.740 > Author: eem > Time: 29 May 2015, 4:09:46.189 pm > UUID: 53894fe9-e3f5-44c7-b4c2-101e4d72f0d3 > Ancestors: System-eem.739 > > Modify condensSources to preserve direct method history. > > =============== Diff against System-eem.739 =============== > > Item was changed: > ----- Method: SmalltalkImage>>condenseSources (in category 'housekeeping') ----- > condenseSources > "Move all the changes onto a compacted sources file." > "Smalltalk condenseSources" > > | newSourcesFile defaultDirectory newVersion currentVersion | > Utilities fixUpProblemsWithAllCategory. > "The above removes any concrete, spurious '-- all --' categories, which mess up the process." > defaultDirectory := FileDirectory default. > currentVersion := self sourceFileVersionString. > newVersion := UIManager default > request: 'Please designate the version\for the new source code file...' withCRs > initialAnswer: currentVersion. > newVersion ifEmpty: [ ^ self ]. > newVersion = currentVersion ifTrue: [ ^ self error: 'The new source file must not be the same as the old.' ]. > self sourceFileVersionString: newVersion. > > "Write all sources with fileIndex 1" > newSourcesFile := defaultDirectory newFileNamed: (defaultDirectory localNameFor: self sourcesName). > newSourcesFile ifNil: [ ^ self error: 'Couldn''t create source code file in\' withCRs, defaultDirectory name]. > newSourcesFile > header; > timeStamp. > 'Condensing Sources File...' > displayProgressFrom: 0 > to: self classNames size + self traitNames size > during: > [ :bar | > | count | > count := 0. > Smalltalk allClassesAndTraitsDo: > [ :classOrTrait | > bar value: (count := count + 1). > classOrTrait > fileOutOn: newSourcesFile > + moveSource: #historically > - moveSource: true > toFile: 1 ] ]. > newSourcesFile > trailer; > close. > > "Make a new empty changes file" > self closeSourceFiles. > defaultDirectory > rename: self changesName > toBe: self changesName , '.old'. > (FileStream newFileNamed: self changesName) > header; > timeStamp; > close. > self lastQuitLogPosition: 0. > self setMacFileInfoOn: self changesName. > self setMacFileInfoOn: newSourcesFile name. > self openSourceFiles. > self inform: 'Source files have been rewritten to\' withCRs, newSourcesFile name, '\Check that all is well,\and then save/quit.' withCRs! > > From commits at source.squeak.org Fri May 29 23:29:17 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:29:22 2015 Subject: [squeak-dev] The Trunk: Collections.spur-eem.636.mcz Message-ID: Eliot Miranda uploaded a new version of Collections to project The Trunk: http://source.squeak.org/trunk/Collections.spur-eem.636.mcz ==================== Summary ==================== Name: Collections.spur-eem.636 Author: eem Time: 29 May 2015, 4:26:29.424 pm UUID: b341b330-e1ef-455e-9880-7b782cc4f014 Ancestors: Collections-eem.636, Collections.spur-mt.635 Collections-eem.636 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 findLast:startingAt: dual for findFirst:startingAt: =============== Diff against Collections-eem.636 =============== Item was changed: ----- Method: Array>>elementsExchangeIdentityWith: (in category 'converting') ----- elementsExchangeIdentityWith: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + At the same time, all pointers to the elements of otherArray are replaced by + pointers to the corresponding elements of this array. The identityHashes remain + with the pointers rather than with the objects so that objects in hashed structures + should still be properly indexed after the mutation." - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. At the same time, all pointers to the elements of otherArray are replaced by pointers to the corresponding elements of this array. The identityHashes remain with the pointers rather than with the objects so that objects in hashed structures should still be properly indexed after the mutation." + + ec == #'bad receiver' ifTrue: + [^self error: 'receiver must be of class Array']. + ec == #'bad argument' ifTrue: + [^self error: (otherArray class == Array + ifTrue: ['arg must be of class Array'] + ifFalse: ['receiver and argument must have the same size'])]. + ec == #'inappropriate operation' ifTrue: + [^self error: 'can''t become immediates such as SmallIntegers or Characters']. + ec == #'no modification' ifTrue: + [^self error: 'can''t become immutable objects']. + ec == #'object is pinned' ifTrue: + [^self error: 'can''t become pinned objects']. + ec == #'insufficient object memory' ifTrue: + [Smalltalk garbageCollect < 1048576 ifTrue: + [Smalltalk growMemoryByAtLeast: 1048576]. + ^self elementsExchangeIdentityWith: otherArray]. + self primitiveFailed! - - otherArray class == Array ifFalse: [^ self error: 'arg must be array']. - self size = otherArray size ifFalse: [^ self error: 'arrays must be same size']. - (self anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - (otherArray anySatisfy: [:obj | obj class == SmallInteger]) ifTrue: [^ self error: 'can''t become SmallIntegers']. - self with: otherArray do:[:a :b| a == b ifTrue:[^self error:'can''t become yourself']]. - - "Must have failed because not enough space in forwarding table (see ObjectMemory-prepareForwardingTableForBecoming:with:twoWay:). Do GC and try again only once" - (Smalltalk bytesLeft: true) = Smalltalk primitiveGarbageCollect - ifTrue: [^ self primitiveFailed]. - ^ self elementsExchangeIdentityWith: otherArray! Item was changed: ----- Method: Array>>elementsForwardIdentityTo: (in category 'converting') ----- elementsForwardIdentityTo: otherArray + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + The identityHashes remain with the pointers rather than with the objects so that + the objects in this array should still be properly indexed in any existing hashed + structures after the mutation." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ----- Method: Array>>elementsForwardIdentityTo:copyHash: (in category 'converting') ----- elementsForwardIdentityTo: otherArray copyHash: copyHash + "This primitive performs a bulk mutation, causing all pointers to the elements of the + receiver to be replaced by pointers to the corresponding elements of otherArray. + If copyHash is true, the identityHashes remain with the pointers rather than with the + objects so that the objects in the receiver should still be properly indexed in any + existing hashed structures after the mutation. If copyHash is false, then the hashes + of the objects in otherArray remain unchanged. If you know what you're doing this + may indeed be what you want." + - "This primitive performs a bulk mutation, causing all pointers to the elements of this array to be replaced by pointers to the corresponding elements of otherArray. The identityHashes remain with the pointers rather than with the objects so that the objects in this array should still be properly indexed in any existing hashed structures after the mutation." - self primitiveFailed! Item was changed: ==== ERROR === Error: Unrecognized class type 29 May 2015 11:29:12.996 pm VM: unix - a SmalltalkImage Image: Squeak3.11alpha [latest update: #8824] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /home/squeaksource Trusted Dir /home/squeaksource/secure Untrusted Dir /home/squeaksource/My Squeak MCClassDefinition(Object)>>error: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: aString: 'Unrecognized class type' Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>kindOfSubclass Receiver: a MCClassDefinition(Character) Arguments and temporary variables: Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil MCClassDefinition>>printDefinitionOn: Receiver: a MCClassDefinition(Character) Arguments and temporary variables: stream: a WriteStream Receiver's instance variables: name: #Character superclassName: #Magnitude variables: an OrderedCollection(a MCClassVariableDefinition(AlphaNumericMask) a...etc... category: #'Collections-Strings' type: #immediate comment: 'I represent a character by storing its associated Unicode as an unsig...etc... commentStamp: 'eem 8/12/2014 14:53' traitComposition: nil classTraitComposition: nil [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: Receiver: a MCDiffyTextWriter Arguments and temporary variables: definition: a WriteStream s: a MCClassDefinition(Character) Receiver's instance variables: stream: a WriteStream initStream: nil --- The full stack --- MCClassDefinition(Object)>>error: MCClassDefinition>>kindOfSubclass MCClassDefinition>>printDefinitionOn: [] in MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>chunkContents: MCDiffyTextWriter(MCStWriter)>>writeClassDefinition: MCDiffyTextWriter(MCStWriter)>>visitClassDefinition: MCClassDefinition>>accept: [] in MCDiffyTextWriter(MCTextWriter)>>visitInFork: String class(SequenceableCollection class)>>new:streamContents: String class(SequenceableCollection class)>>streamContents: MCDiffyTextWriter(MCTextWriter)>>visitInFork: MCDiffyTextWriter>>writePatchFrom:to: MCDiffyTextWriter>>writeModification: [] in MCDiffyTextWriter>>writePatch: SortedCollection(OrderedCollection)>>do: MCDiffyTextWriter>>writePatch: SSDiffyTextWriter>>writePatch: [] in SSDiffyTextWriter>>writeVersion:for: BlockClosure>>on:do: SSDiffyTextWriter>>writeVersion:for: [] in SSEMailSubscription>>versionAdded:to: BlockClosure>>on:do: SSEMailSubscription>>versionAdded:to: [] in [] in SSProject>>versionAdded: [] in BlockClosure>>newProcess From commits at source.squeak.org Fri May 29 23:29:17 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:29:28 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.298.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.298.mcz ==================== Summary ==================== Name: Compiler.spur-eem.298 Author: eem Time: 29 May 2015, 4:27:51.392 pm UUID: 929039ad-58e2-40e1-82c9-887b6df58153 Ancestors: Compiler-eem.298, Compiler.spur-cmm.297 Compiler-eem.298 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Provide multiple-bytecode-sets aware support for markerOrNil =============== Diff against Compiler-eem.298 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Fri May 29 23:29:32 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:29:43 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.299.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.299.mcz ==================== Summary ==================== Name: Compiler.spur-eem.299 Author: eem Time: 29 May 2015, 4:27:59.664 pm UUID: 85f293a2-b374-4879-971a-049a9dbb1ff9 Ancestors: Compiler-eem.299, Compiler.spur-eem.298 Compiler-eem.299 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Provide support for a specialized pushNClosureTemps: bytecode, as included in the Sista bytecode set. =============== Diff against Compiler-eem.299 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Fri May 29 23:30:00 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:30:04 2015 Subject: [squeak-dev] The Trunk: Compiler.spur-eem.300.mcz Message-ID: Eliot Miranda uploaded a new version of Compiler to project The Trunk: http://source.squeak.org/trunk/Compiler.spur-eem.300.mcz ==================== Summary ==================== Name: Compiler.spur-eem.300 Author: eem Time: 29 May 2015, 4:28:02.94 pm UUID: 876db460-d55d-4dd8-8f53-3e78f6492e39 Ancestors: Compiler-eem.300, Compiler.spur-eem.299 Compiler-eem.300 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Use the size/emitPushNClosureTemps: api in block generation. =============== Diff against Compiler-eem.300 =============== Item was changed: ----- Method: BytecodeEncoder>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex + numArgs > 15 ifTrue: + [^self error: 'Cannot compile -- too many arguments']. + numTemps > 63 ifTrue: + [^self error: 'Cannot compile -- too many temporary variables']. + numLits > 65535 ifTrue: + [^self error: 'Cannot compile -- too many literals']. + ^(CompiledMethod headerFlagForEncoder: self) + + (numArgs bitShift: 24) + + (numTemps bitShift: 18) + "+ (largeBit bitShift: 17)" "largeBit gets filled in later" + + (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]) + + numLits! - "Compute the compiled method header that encodes the arguments - in the receiver's header format (see CompiledMehtod's class comment)." - self subclassResponsibility! Item was removed: - ----- Method: EncoderForV3>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive: (in category 'method generation') ----- - computeMethodHeaderForNumArgs: numArgs numTemps: numTemps numLits: numLits primitive: primitiveIndex - | primBits | - numTemps > 63 ifTrue: - [^self error: 'Cannot compile -- too many temporary variables']. - numLits > 255 ifTrue: - [^self error: 'Cannot compile -- too many literals']. - primBits := primitiveIndex <= 16r1FF - ifTrue: [primitiveIndex] - ifFalse: "For now the high bit of primitive no. is in the 29th bit of header" - [primitiveIndex > 16r3FF ifTrue: [self error: 'prim num too large']. - (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)]. - ^(numArgs bitShift: 24) - + (numTemps bitShift: 18) - "+ (largeBit bitShift: 17)" "largeBit gets filled in later" - + (numLits bitShift: 9) - + primBits! Item was changed: ----- Method: EncoderForV3PlusClosures class>>bytecodeSize: (in category 'instruction stream support') ----- bytecodeSize: bytecode "Answer the number of bytes in the bytecode." bytecode <= 125 ifTrue: [^1]. bytecode >= 176 ifTrue: [^1]. bytecode >= 160 ifTrue: "long jumps" [^2]. bytecode >= 144 ifTrue: "short jumps" [^1]. "extensions" bytecode >= 128 ifTrue: + [^#(2 2 2 2 3 2 2 1 1 1 2 3 3 3 3 4) at: bytecode - 127]. - [^#(2 2 2 2 3 2 2 1 1 1 2 nil 3 3 3 4) at: bytecode - 127]. ^nil! Item was added: + ----- Method: EncoderForV3PlusClosures class>>callPrimitiveCode (in category 'bytecode decoding') ----- + callPrimitiveCode + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + ^139! Item was added: + ----- Method: EncoderForV3PlusClosures>>genCallPrimitive: (in category 'bytecode generation') ----- + genCallPrimitive: primitiveIndex + "139 11101111 iiiiiiii jjjjjjjj Call Primitive #iiiiiiii + (jjjjjjjj * 256)" + (primitiveIndex < 1 or: [primitiveIndex > 65535]) ifTrue: + [self outOfRangeError: 'primitive index' index: primitiveIndex range: 1 to: 65535]. + stream + nextPut: 139; + nextPut: (primitiveIndex bitAnd: 255); + nextPut: (primitiveIndex bitShift: -8)! Item was changed: ----- Method: MethodNode>>generate:using: (in category 'code generation') ----- generate: trailer using: aCompiledMethodClass "The receiver is the root of a parse tree. Answer an instance of aCompiledMethodClass. The argument, trailer, is arbitrary but is typically either the reference to the source code that is stored with every CompiledMethod, or an encoding of the method's temporary names." + | primErrNode blkSize nLits locals literals stack header method | - | primErrNode blkSize nLits literals stack method | self generate: trailer using: aCompiledMethodClass ifQuick: [:m | encoder noteBlockExtent: (0 to: 2) hasLocals: arguments. m literalAt: 2 put: encoder associationForClass; properties: properties. ^m]. primErrNode := self primitiveErrorVariableName ifNotNil: [encoder fixTemp: self primitiveErrorVariableName]. + self ensureClosureAnalysisDone. + encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:" - encoder supportsClosureOpcodes ifTrue: - [self ensureClosureAnalysisDone. - encoder rootNode: self. "this is for BlockNode>>sizeCodeForClosureValue:"]. blkSize := (block sizeCodeForEvaluatedValue: encoder) + + (primitive > 0 + ifTrue: [encoder sizeCallPrimitive: primitive] + ifFalse: [0]) + (primErrNode ifNil: [0] ifNotNil: [primErrNode index: arguments size + temporaries size; sizeCodeForStore: encoder "The VM relies on storeIntoTemp: (129)"]). + locals := arguments, temporaries, (primErrNode ifNil: [#()] ifNotNil: [{primErrNode}]). + encoder noteBlockExtent: block blockExtent hasLocals: locals. + header := encoder computeMethodHeaderForNumArgs: arguments size + numTemps: locals size + numLits: (nLits := (literals := encoder allLiterals) size) + primitive: primitive. + method := trailer + createMethod: blkSize + class: aCompiledMethodClass + header: header. - method := aCompiledMethodClass - newBytes: blkSize - trailerBytes: trailer - nArgs: arguments size - nTemps: (encoder supportsClosureOpcodes - ifTrue: [| locals | - locals := arguments, - temporaries, - (primErrNode - ifNil: [#()] - ifNotNil: [{primErrNode}]). - encoder - noteBlockExtent: block blockExtent - hasLocals: locals. - locals size] - ifFalse: [encoder maxTemp]) - nStack: 0 - nLits: (nLits := (literals := encoder allLiterals) size) - primitive: primitive. - nLits > 255 ifTrue: - [^self error: 'Too many literals referenced']. 1 to: nLits do: [:lit | method literalAt: lit put: (literals at: lit)]. encoder streamToMethod: method. stack := ParseStack new init. + primitive > 0 ifTrue: + [encoder genCallPrimitive: primitive. + primErrNode ifNotNil: + [primErrNode emitCodeForStore: stack encoder: encoder]]. - primErrNode ifNotNil: [primErrNode emitCodeForStore: stack encoder: encoder]. stack position: method numTemps. [block emitCodeForEvaluatedValue: stack encoder: encoder] on: Error "If an attempt is made to write too much code the method will be asked" do: [:ex| "to grow, and the grow attempt will fail in CompiledMethod class>>#new:" ex signalerContext sender method = (CompiledMethod class>>#new:) ifTrue: [^self error: 'Compiler code size discrepancy'] ifFalse: [ex pass]]. stack position ~= (method numTemps + 1) ifTrue: [^self error: 'Compiler stack discrepancy']. encoder methodStreamPosition ~= (method size - trailer size) ifTrue: [^self error: 'Compiler code size discrepancy']. method needsFrameSize: stack size - method numTemps. method properties: properties. ^method! From commits at source.squeak.org Fri May 29 23:33:33 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:33:35 2015 Subject: [squeak-dev] The Trunk: System.spur-cmm.738.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-cmm.738.mcz ==================== Summary ==================== Name: System.spur-cmm.738 Author: eem Time: 29 May 2015, 4:28:11.979 pm UUID: 84a28675-cf59-465f-86cc-58e2b38557bc Ancestors: System-cmm.738, System.spur-ul.737 System-cmm.738 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Fix #run: leaving headless image stuck because there was a MNU or Halt. =============== Diff against System-cmm.738 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Fri May 29 23:33:54 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:33:57 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.739.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.739.mcz ==================== Summary ==================== Name: System.spur-eem.739 Author: eem Time: 29 May 2015, 4:28:17.452 pm UUID: fe7a0115-0706-4a19-a2b1-280f5a7e50d6 Ancestors: System-eem.739, System.spur-cmm.738 System-eem.739 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Support for condensing sources and changes while preserving direct history. =============== Diff against System-eem.739 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From commits at source.squeak.org Fri May 29 23:34:26 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Fri May 29 23:34:28 2015 Subject: [squeak-dev] The Trunk: System.spur-eem.740.mcz Message-ID: Eliot Miranda uploaded a new version of System to project The Trunk: http://source.squeak.org/trunk/System.spur-eem.740.mcz ==================== Summary ==================== Name: System.spur-eem.740 Author: eem Time: 29 May 2015, 4:28:22.56 pm UUID: 8f35651e-68da-4766-8099-e16dd553260d Ancestors: System-eem.740, System.spur-eem.739 System-eem.740 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Modify condensSources to preserve direct method history. =============== Diff against System-eem.740 =============== Item was removed: - Object subclass: #ObjectHistory - instanceVariableNames: 'marks markProcess' - classVariableNames: 'Current ObjectHistoryEnabled' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistory commentStamp: 'bf 11/16/2012 12:19' prior: 0! - ObjectHistory holds ObjectHistoryMark objects which are placed in the object memory at regular intervals by its markProcess in the background. Adjacent marks (with no remaining objects inbetween) are coalesced so over time the collection does not grow unnecessarily large. - - Using these markers it is possible to determine the age of objects in memory from the time the ObjectHistory was initialized. Try e.g.: - self oopTimestamp. - self oopAge. - ObjectHistory current oopClassesByDate. - - Instance Variables - marks: SortedCollection of ObjectHistoryMark objects - markProcess: a Process running our markLoop - ! Item was removed: - ----- Method: ObjectHistory class>>current (in category 'accessing') ----- - current - ^ Current ifNil: [Current := self new]! Item was removed: - ----- Method: ObjectHistory class>>initialize (in category 'class initialization') ----- - initialize - self current. - ! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory (in category 'preferences') ----- - keepTrackOfObjectHistory - - ^ ObjectHistoryEnabled ifNil: [ - Current - ifNil: [false] - ifNotNil: [:objectHistory | objectHistory isRunning]]! Item was removed: - ----- Method: ObjectHistory class>>keepTrackOfObjectHistory: (in category 'preferences') ----- - keepTrackOfObjectHistory: aBoolean - " Reflect the desired state by starting/stopping the process if necessary " - ObjectHistoryEnabled = aBoolean ifTrue: [^ self]. - ObjectHistoryEnabled := aBoolean. - - Current - ifNil: [aBoolean ifTrue: [self current]] - ifNotNil: [:objectHistory | - (objectHistory isRunning xor: aBoolean) "state switch needed" - ifTrue: [objectHistory toggleRunning]].! Item was removed: - ----- Method: ObjectHistory class>>obsolete (in category 'class initialization') ----- - obsolete - "Kill the mark process before removing the class." - Current ifNotNil: - [:objectHistory| - objectHistory terminate]. - super obsolete! Item was removed: - ----- Method: ObjectHistory>>ageOf: (in category 'queries') ----- - ageOf: anObject - "Age of anObject in seconds" - | timestamp | - timestamp := self timestampOf: anObject. - timestamp ifNil: [^0]. - ^(DateAndTime now - timestamp) asSeconds roundTo: self markRate! Item was removed: - ----- Method: ObjectHistory>>initialize (in category 'initializing') ----- - initialize - self restartMarkProcess. - - ! Item was removed: - ----- Method: ObjectHistory>>isRunning (in category 'testing') ----- - isRunning - ^ markProcess - ifNil: [false] - ifNotNil: [:process | - process isSuspended not and: [ - process isTerminated not]]! Item was removed: - ----- Method: ObjectHistory>>markLoop (in category 'marking') ----- - markLoop - [true] whileTrue: [ - self markUpdate. - (Delay forSeconds: self markRate) wait]! Item was removed: - ----- Method: ObjectHistory>>markRate (in category 'marking') ----- - markRate - "rate of creating ObjectHistoryMarks" - ^60! Item was removed: - ----- Method: ObjectHistory>>markUpdate (in category 'marking') ----- - markUpdate - "Add a new mark and compact the marks collection" - | mark prev | - "lazy init so this happens in the background process" - marks ifNil: [self reinitMarks]. - "add new mark to object memory" - mark := self newMark. - mark timestamp <= marks last timestamp ifTrue: [^self "could happen if clock is wrong"]. - marks addLast: mark. - "compact the table by removing adjacent marks" - prev := marks first. - marks removeAllSuchThat: [:each | | doDelete | - doDelete := prev objectAfter == each. - prev := each. - doDelete]. - "The loop above is O(n) in number of marks, but that number should never become so large to be an issue. Even if the number was large, this is running at system background priority so should not interfere with any user process, not even user background processes. The symptom should only be that the system is less idle. - - If we ever get to a point where the number of marks is an issue then the compacting here could be made partial: since old marks rarely get coalesced it would make sense to only check the newer ones often, and the old ones perhaps only at the system startup."! Item was removed: - ----- Method: ObjectHistory>>newMark (in category 'private') ----- - newMark - ^ ObjectHistoryMark new! Item was removed: - ----- Method: ObjectHistory>>oopClassesByAge (in category 'stats') ----- - oopClassesByAge - "Answer collection of (oopAge in seconds -> sorted counts of object classes) sorted from lowest age" - "ObjectHistory current oopClassesByAge" - - | stats prev endOfMemory now bag age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - bag := Bag new. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> bag sortedCounts]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopClassesByDate (in category 'stats') ----- - oopClassesByDate - "Answer collection of (Date -> sorted counts of object classes) sorted from newest date" - "ObjectHistory current oopClassesByDate" - - | stats prev endOfMemory bag date obj thisDate | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - thisDate := nil. - bag := Bag new. - marks do: [:mark | - prev ifNotNil: [ - obj := prev objectAfter. - [obj == mark] whileFalse: [ - bag add: obj class. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - date := mark timestamp asDate. - thisDate = date ifFalse: [ - stats addFirst: date -> bag sortedCounts. - bag := Bag new. - thisDate := date]]. - prev := mark]. - thisDate = date ifFalse: [ - stats addLast: date -> bag sortedCounts]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>oopCountsByAge (in category 'stats') ----- - oopCountsByAge - "Answer collection of (oopAge in seconds -> number of objects) sorted from lowest age" - "ObjectHistory current oopCountsByAge" - - | stats prev endOfMemory now n age obj | - endOfMemory := Object new. - stats := OrderedCollection new: 1000. - prev := nil. - now := self newMark timestamp. - marks do: [:mark | - prev ifNotNil: [ - n := 0. - obj := prev objectAfter. - [obj == mark] whileFalse: [ - n := n + 1. - obj := obj nextObject. - obj == endOfMemory ifTrue: [self error: 'should not happen']]. - age := (now - mark timestamp) asSeconds roundTo: self markRate. - stats addFirst: age -> n]. - prev := mark]. - ^ stats - ! Item was removed: - ----- Method: ObjectHistory>>reinitMarks (in category 'private') ----- - reinitMarks - marks := ObjectHistoryMark allInstances asOrderedCollection. - marks - ifEmpty: [marks add: self newMark] - ifNotEmpty: [ | prev | - prev := nil. - marks removeAllSuchThat: [:obj | - prev notNil and: [prev timestamp >= obj timestamp]]]. - ! Item was removed: - ----- Method: ObjectHistory>>restartMarkProcess (in category 'marking') ----- - restartMarkProcess - markProcess ifNotNil: [markProcess terminate]. - markProcess := [self markLoop] - forkAt: Processor systemBackgroundPriority - named: 'ObjectHistory''s markProcess'. - ! Item was removed: - ----- Method: ObjectHistory>>terminate (in category 'private') ----- - terminate - markProcess ifNotNil: - [markProcess terminate]! Item was removed: - ----- Method: ObjectHistory>>timestampOf: (in category 'queries') ----- - timestampOf: anObject - "Timestamp of anObject, or nil if too new" - | endOfMemory mark | - anObject class == SmallInteger ifTrue: [^nil]. - mark := anObject. - endOfMemory := Object new. - [mark class == ObjectHistoryMark] whileFalse: [ - mark := mark nextObject. - mark == endOfMemory ifTrue: [^nil]]. - ^mark timestamp! Item was removed: - ----- Method: ObjectHistory>>toggleRunning (in category 'private') ----- - toggleRunning - self isRunning - ifTrue: [self terminate] - ifFalse: [self restartMarkProcess]! Item was removed: - Object subclass: #ObjectHistoryMark - instanceVariableNames: 'timestamp' - classVariableNames: '' - poolDictionaries: '' - category: 'System-Support'! - - !ObjectHistoryMark commentStamp: 'bf 11/7/2012 00:12' prior: 0! - An ObjectHistoryMark is a permanent mark in the object memory. It holds a timestamp. - - While the timestamp could be used directly as mark by ObjectHistory, it's conceivable that its format might change in the future, and we do not want the mark's relative position in memory to change (which would be the case if it was migrated to a new format). So we use a distinct object instead (and we protect it against accidental become-ing by overriding those methods).! Item was removed: - ----- Method: ObjectHistoryMark>>become: (in category 'mutating') ----- - become: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>becomeForward: (in category 'mutating') ----- - becomeForward: otherObject - ^self error: 'marks need to stay fixed in the object memory'! Item was removed: - ----- Method: ObjectHistoryMark>>initialize (in category 'initialization') ----- - initialize - timestamp := DateAndTime now floor. - ! Item was removed: - ----- Method: ObjectHistoryMark>>objectAfter (in category 'accessing') ----- - objectAfter - "Answer the next object in memory after me and my timestamp" - | successor | - successor := self nextObject. - successor == timestamp - ifTrue: [successor := successor nextObject]. - ^ successor! Item was removed: - ----- Method: ObjectHistoryMark>>printOn: (in category 'printing') ----- - printOn: aStream - aStream - nextPutAll: self class name; - nextPut: $(; - print: timestamp; - nextPut: $)! Item was removed: - ----- Method: ObjectHistoryMark>>timestamp (in category 'accessing') ----- - timestamp - ^timestamp - ! Item was changed: ----- Method: SmalltalkImage>>compactClassesArray (in category 'special objects') ----- compactClassesArray "Smalltalk compactClassesArray" + "Backward-compatibility support. Spur does not have compact classes." + ^{}! - "Return the array of 31 classes whose instances may be - represented compactly" - ^ self specialObjectsArray at: 29! Item was added: + ----- Method: SmalltalkImage>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Essential. Fail if no memory is available." + + (numBytes isInteger and: [numBytes > 0]) ifTrue: + [OutOfMemory signal]. + ^self primitiveFailed! Item was added: + ----- Method: SmalltalkImage>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was changed: ----- Method: SmalltalkImage>>primBytesLeft (in category 'memory space') ----- primBytesLeft + "Primitive. Answer the number of free bytes available in old space. + Not accurate unless preceded by - "Primitive. Answer the number of bytes available for new object data. - Not accurate unless preceded by Smalltalk garbageCollectMost (for reasonable accuracy), or Smalltalk garbageCollect (for real accuracy). + See Object documentation whatIsAPrimitive." - See Object documentation whatIsAPrimitive." + ^0! - ^ 0! Item was changed: ----- Method: SmalltalkImage>>primitiveGarbageCollect (in category 'memory space') ----- primitiveGarbageCollect + "Primitive. Reclaims all garbage and answers the size of the largest free chunk in old space.." - "Primitive. Reclaims all garbage and answers the number of bytes of available space." + ^self primitiveFailed! - ^ self primBytesLeft! Item was changed: ----- Method: SmalltalkImage>>recreateSpecialObjectsArray (in category 'special objects') ----- recreateSpecialObjectsArray "Smalltalk recreateSpecialObjectsArray" "To external package developers: **** DO NOT OVERRIDE THIS METHOD. ***** If you are writing a plugin and need additional special object(s) for your own use, use addGCRoot() function and use own, separate special objects registry " "The Special Objects Array is an array of objects used by the Squeak virtual machine. Its contents are critical and accesses to it by the VM are unchecked, so don't even think of playing here unless you know what you are doing." | newArray | + newArray := Array new: 60. - newArray := Array new: 58. "Nil false and true get used throughout the interpreter" newArray at: 1 put: nil. newArray at: 2 put: false. newArray at: 3 put: true. "This association holds the active process (a ProcessScheduler)" newArray at: 4 put: (self specialObjectsArray at: 4) "(self bindingOf: #Processor) but it answers an Alias". "Numerous classes below used for type checking and instantiation" newArray at: 5 put: Bitmap. newArray at: 6 put: SmallInteger. newArray at: 7 put: ByteString. newArray at: 8 put: Array. newArray at: 9 put: Smalltalk. + newArray at: 10 put: BoxedFloat64. + newArray at: 11 put: (self globals at: #MethodContext ifAbsent: [self globals at: #Context]). + newArray at: 12 put: nil. "was BlockContext." - newArray at: 10 put: Float. - newArray at: 11 put: MethodContext. - newArray at: 12 put: BlockContext. newArray at: 13 put: Point. newArray at: 14 put: LargePositiveInteger. newArray at: 15 put: Display. newArray at: 16 put: Message. newArray at: 17 put: CompiledMethod. + newArray at: 18 put: ((self specialObjectsArray at: 18) ifNil: [Semaphore new]). "low space Semaphore" - newArray at: 18 put: (self specialObjectsArray at: 18). - "(low space Semaphore)" newArray at: 19 put: Semaphore. newArray at: 20 put: Character. newArray at: 21 put: #doesNotUnderstand:. newArray at: 22 put: #cannotReturn:. newArray at: 23 put: nil. "This is the process signalling low space." "An array of the 32 selectors that are compiled as special bytecodes, paired alternately with the number of arguments each takes." newArray at: 24 put: #( #+ 1 #- 1 #< 1 #> 1 #<= 1 #>= 1 #= 1 #~= 1 #* 1 #/ 1 #\\ 1 #@ 1 #bitShift: 1 #// 1 #bitAnd: 1 #bitOr: 1 #at: 1 #at:put: 2 #size 0 #next 0 #nextPut: 1 #atEnd 0 #== 1 #class 0 #blockCopy: 1 #value 0 #value: 1 #do: 1 #new 0 #new: 1 #x 0 #y 0 ). "An array of the 255 Characters in ascii order. + Cog inlines table into machine code at: prim so do not regenerate it. + This is nil in Spur, which has immediate Characters." - Cog inlines table into machine code at: prim so do not regenerate it." newArray at: 25 put: (self specialObjectsArray at: 25). newArray at: 26 put: #mustBeBoolean. newArray at: 27 put: ByteArray. newArray at: 28 put: Process. + "An array of up to 31 classes whose instances will have compact headers; an empty array in Spur" - "An array of up to 31 classes whose instances will have compact headers" newArray at: 29 put: self compactClassesArray. + newArray at: 30 put: ((self specialObjectsArray at: 30) ifNil: [Semaphore new]). "delay Semaphore" + newArray at: 31 put: ((self specialObjectsArray at: 31) ifNil: [Semaphore new]). "user interrupt Semaphore" - newArray at: 30 put: (self specialObjectsArray at: 30). "(delay Semaphore)" - newArray at: 31 put: (self specialObjectsArray at: 31). "(user interrupt Semaphore)" "Entries 32 - 34 unreferenced. Previously these contained prototype instances to be copied for fast initialization" + newArray at: 32 put: nil. "was the prototype Float" + newArray at: 33 put: nil. "was the prototype 4-byte LargePositiveInteger" + newArray at: 34 put: nil. "was the prototype Point" - newArray at: 32 put: nil. "was (Float new: 2)" - newArray at: 33 put: nil. "was (LargePositiveInteger new: 4)" - newArray at: 34 put: nil. "was Point new" newArray at: 35 put: #cannotInterpret:. + newArray at: 36 put: nil. "was the prototype MethodContext" - "Note: This must be fixed once we start using context prototypes (yeah, right)" - "(MethodContext new: CompiledMethod fullFrameSize)." - newArray at: 36 put: (self specialObjectsArray at: 36). "Is the prototype MethodContext (unused by the VM)" newArray at: 37 put: BlockClosure. + newArray at: 38 put: nil. "was the prototype BlockContext" - "(BlockContext new: CompiledMethod fullFrameSize)." - newArray at: 38 put: (self specialObjectsArray at: 38). "Is the prototype BlockContext (unused by the VM)" "array of objects referred to by external code" + newArray at: 39 put: (self specialObjectsArray at: 39). "external semaphores" - newArray at: 39 put: (self specialObjectsArray at: 39). "preserve external semaphores" newArray at: 40 put: nil. "Reserved for Mutex in Cog VMs" + newArray at: 41 put: ((self specialObjectsArray at: 41) ifNil: [LinkedList new]). "Reserved for a LinkedList instance for overlapped calls in CogMT" + newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). "finalization Semaphore" - newArray at: 41 put: nil. "Reserved for a LinkedList instance for overlapped calls in CogMT" - "finalization Semaphore" - newArray at: 42 put: ((self specialObjectsArray at: 42) ifNil: [Semaphore new]). newArray at: 43 put: LargeNegativeInteger. "External objects for callout. Note: Written so that one can actually completely remove the FFI." newArray at: 44 put: (self at: #ExternalAddress ifAbsent: []). newArray at: 45 put: (self at: #ExternalStructure ifAbsent: []). newArray at: 46 put: (self at: #ExternalData ifAbsent: []). newArray at: 47 put: (self at: #ExternalFunction ifAbsent: []). newArray at: 48 put: (self at: #ExternalLibrary ifAbsent: []). newArray at: 49 put: #aboutToReturn:through:. newArray at: 50 put: #run:with:in:. "51 reserved for immutability message" + newArray at: 51 put: #attemptToAssign:withIndex:. - "newArray at: 51 put: #attemptToAssign:withIndex:." - newArray at: 51 put: (self specialObjectsArray at: 51 ifAbsent: []). newArray at: 52 put: #(nil "nil => generic error" #'bad receiver' #'bad argument' #'bad index' #'bad number of arguments' #'inappropriate operation' #'unsupported operation' #'no modification' #'insufficient object memory' #'insufficient C memory' #'not found' #'bad method' #'internal error in named primitive machinery' #'object may move' #'resource limit exceeded' + #'object is pinned' #'primitive write beyond end of object'). - #'object is pinned'). "53 to 55 are for Alien" newArray at: 53 put: (self at: #Alien ifAbsent: []). + newArray at: 54 put: #invokeCallbackContext:. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." - newArray at: 54 put: #invokeCallbackContext::. "use invokeCallback:stack:registers:jmpbuf: for old Alien callbacks." newArray at: 55 put: (self at: #UnsafeAlien ifAbsent: []). + "Used to be WeakFinalizationList for WeakFinalizationList hasNewFinalization, obsoleted by ephemeron support." + newArray at: 56 put: nil. - "Weak reference finalization" - newArray at: 56 put: (self at: #WeakFinalizationList ifAbsent: []). "reserved for foreign callback process" newArray at: 57 put: (self specialObjectsArray at: 57 ifAbsent: []). newArray at: 58 put: #unusedBytecode. + "59 reserved for Sista counter tripped message" + newArray at: 59 put: #conditionalBranchCounterTrippedOn:. + "60 reserved for Sista class trap message" + newArray at: 60 put: #classTrapFor:. "Now replace the interpreter's reference in one atomic operation" + self specialObjectsArray becomeForward: newArray! - self specialObjectsArray becomeForward: newArray - ! Item was changed: ----- Method: SmalltalkImage>>setGCParameters (in category 'snapshot and quit') ----- setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" - "Adjust the VM's default GC parameters to avoid premature tenuring." + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! - self vmParameterAt: 5 put: 4000. "do an incremental GC after this many allocations" - self vmParameterAt: 6 put: 2000. "tenure when more than this many objects survive the GC" - ! Item was changed: ----- Method: SpaceTally>>spaceForInstancesOf: (in category 'instance size') ----- spaceForInstancesOf: aClass + "Answer a pair of the number of bytes consumed by all instances of the + given class, including their object headers, and the number of instances." - "Answer the number of bytes consumed by all instances of the given class, including their object headers and the number of instances." + | instances total | + instances := aClass allInstances. + instances isEmpty ifTrue: [^#(0 0)]. - | smallHeaderSize instVarBytes isVariable bytesPerElement total lastInstance instance instanceCount | - instance := aClass someInstance ifNil: [ ^#(0 0) ]. - smallHeaderSize := aClass isCompact ifTrue: [ 4 ] ifFalse: [ 8 ]. - instVarBytes := aClass instSize * 4. - isVariable := aClass isVariable. - bytesPerElement := isVariable - ifFalse: [ 0 ] - ifTrue: [ aClass isBytes ifTrue: [ 1 ] ifFalse: [ 4 ] ]. total := 0. + aClass isVariable + ifTrue: + [instances do: + [:i| total := total + (aClass byteSizeOfInstanceOfSize: i basicSize)]] + ifFalse: + [total := instances size * aClass byteSizeOfInstance]. + ^{ total. instances size }! - instanceCount := 0. - "A modified version of #allInstancesDo: is inlined here. It avoids an infinite loop when another process is creating new instances of aClass." - self flag: #allInstancesDo:. - lastInstance := - aClass == CompiledMethod "CompiledMethod has special format, see its class comment" - ifTrue: [aClass new] - ifFalse: [aClass basicNew]. - [ instance == lastInstance ] whileFalse: [ - | contentBytes headerBytes | - contentBytes := instVarBytes + (isVariable - ifFalse: [ 0 ] - ifTrue: [ instance basicSize * bytesPerElement ]). - headerBytes := contentBytes > 255 - ifTrue: [ 12 ] - ifFalse: [ smallHeaderSize ]. - total := total + headerBytes + (contentBytes roundUpTo: 4). - instanceCount := instanceCount + 1. - instance := instance nextInstance ]. - ^{ total. instanceCount }! Item was added: + ----- Method: SystemDictionary>>growMemoryByAtLeast: (in category 'memory space') ----- + growMemoryByAtLeast: numBytes + "Grow memory by at least the requested number of bytes. + Primitive. Fail if no memory is available. Essential." + + ^(numBytes isInteger and: [numBytes > 0]) + ifTrue: [OutOfMemory signal] + ifFalse: [self primitiveFailed]! Item was added: + ----- Method: SystemDictionary>>maxIdentityHash (in category 'system attributes') ----- + maxIdentityHash + "Answer the maximum identityHash value supported by the VM." + + ^self primitiveFailed! Item was added: + ----- Method: SystemDictionary>>setGCParameters (in category 'snapshot and quit') ----- + setGCParameters + "Adjust the VM's default GC parameters to avoid too much tenuring. + Maybe this should be left to the VM?" + + | proportion edenSize survivorSize averageObjectSize numObjects | + proportion := 0.9. "tenure when 90% of pastSpace is full" + edenSize := SmalltalkImage current vmParameterAt: 44. + survivorSize := edenSize / 5.0. "David's paper uses 140Kb eden + 2 x 28kb survivor spaces; Spur uses the same ratios :-)" + averageObjectSize := 8 * self wordSize. "a good approximation" + numObjects := (proportion * survivorSize / averageObjectSize) rounded. + SmalltalkImage current vmParameterAt: 6 put: numObjects "tenure when more than this many objects survive the GC"! Item was added: + ----- Method: SystemNavigation>>allObjects (in category 'query') ----- + allObjects + "Answer an Array of all objects in the system. Fail if + there isn't enough memory to instantiate the result." + + ^self primitiveFailed! Item was changed: ----- Method: SystemNavigation>>allObjectsDo: (in category 'query') ----- allObjectsDo: aBlock + "Evaluate the argument, aBlock, for each object in the system, excluding immediates + such as SmallInteger and Character." + self allObjectsOrNil + ifNotNil: [:allObjects| allObjects do: aBlock] + ifNil: + ["Fall back on the old single object primitive code. With closures, this needs + to use an end marker (lastObject) since activation of the block will create + new contexts and cause an infinite loop. The lastObject must be created + before calling someObject, so that the VM can settle the enumeration (e.g. + by flushing new space) as a side effect of someObject" + | object lastObject | + lastObject := Object new. + object := self someObject. + [lastObject == object or: [0 == object]] whileFalse: + [aBlock value: object. + object := object nextObject]]! - "Evaluate the argument, aBlock, for each object in the system - excluding SmallIntegers. With closures, this needs to use an end - marker (lastObject) since activation of the block will create new - contexts and cause an infinite loop." - | object lastObject | - object := self someObject. - lastObject := Object new. - [lastObject == object or: [0 == object]] - whileFalse: [aBlock value: object. - object := object nextObject]! Item was added: + ----- Method: SystemNavigation>>allObjectsOrNil (in category 'query') ----- + allObjectsOrNil + "Answer an Array of all objects in the system. Fail if there isn't + enough memory to instantiate the result and answer nil." + + ^nil! From eliot.miranda at gmail.com Sat May 30 00:17:28 2015 From: eliot.miranda at gmail.com (Eliot Miranda) Date: Sat May 30 00:17:31 2015 Subject: [squeak-dev] The Trunk: System-eem.740.mcz In-Reply-To: References: <5568f1e7.76578c0a.229b.1440SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: Hi Chris, On Fri, May 29, 2015 at 4:27 PM, Chris Muller wrote: > Thanks Eliot these features are needed for the release. > So what about the details? here's a straw man. Produce Squeak 4.6's changes file by doing condenseChanges on an updated image, but still keeping SqueakV41.sources as its source file. Produce Squeak 5.0's sources file by doing condenseSources on an undated Spur image, which will result in an empty changes file. > > On Fri, May 29, 2015 at 6:10 PM, wrote: > > Eliot Miranda uploaded a new version of System to project The Trunk: > > http://source.squeak.org/trunk/System-eem.740.mcz > > > > ==================== Summary ==================== > > > > Name: System-eem.740 > > Author: eem > > Time: 29 May 2015, 4:09:46.189 pm > > UUID: 53894fe9-e3f5-44c7-b4c2-101e4d72f0d3 > > Ancestors: System-eem.739 > > > > Modify condensSources to preserve direct method history. > > > > =============== Diff against System-eem.739 =============== > > > > Item was changed: > > ----- Method: SmalltalkImage>>condenseSources (in category > 'housekeeping') ----- > > condenseSources > > "Move all the changes onto a compacted sources file." > > "Smalltalk condenseSources" > > > > | newSourcesFile defaultDirectory newVersion currentVersion | > > Utilities fixUpProblemsWithAllCategory. > > "The above removes any concrete, spurious '-- all --' > categories, which mess up the process." > > defaultDirectory := FileDirectory default. > > currentVersion := self sourceFileVersionString. > > newVersion := UIManager default > > request: 'Please designate the version\for the new > source code file...' withCRs > > initialAnswer: currentVersion. > > newVersion ifEmpty: [ ^ self ]. > > newVersion = currentVersion ifTrue: [ ^ self error: 'The new > source file must not be the same as the old.' ]. > > self sourceFileVersionString: newVersion. > > > > "Write all sources with fileIndex 1" > > newSourcesFile := defaultDirectory newFileNamed: > (defaultDirectory localNameFor: self sourcesName). > > newSourcesFile ifNil: [ ^ self error: 'Couldn''t create source > code file in\' withCRs, defaultDirectory name]. > > newSourcesFile > > header; > > timeStamp. > > 'Condensing Sources File...' > > displayProgressFrom: 0 > > to: self classNames size + self traitNames size > > during: > > [ :bar | > > | count | > > count := 0. > > Smalltalk allClassesAndTraitsDo: > > [ :classOrTrait | > > bar value: (count := count + 1). > > classOrTrait > > fileOutOn: newSourcesFile > > + moveSource: #historically > > - moveSource: true > > toFile: 1 ] ]. > > newSourcesFile > > trailer; > > close. > > > > "Make a new empty changes file" > > self closeSourceFiles. > > defaultDirectory > > rename: self changesName > > toBe: self changesName , '.old'. > > (FileStream newFileNamed: self changesName) > > header; > > timeStamp; > > close. > > self lastQuitLogPosition: 0. > > self setMacFileInfoOn: self changesName. > > self setMacFileInfoOn: newSourcesFile name. > > self openSourceFiles. > > self inform: 'Source files have been rewritten to\' withCRs, > newSourcesFile name, '\Check that all is well,\and then save/quit.' withCRs! > > > > > > -- best, Eliot -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150529/bad29ad6/attachment.htm From commits at source.squeak.org Sat May 30 12:10:20 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 30 12:10:23 2015 Subject: [squeak-dev] The Trunk: MonticelloConfigurations-dtl.135.mcz Message-ID: David T. Lewis uploaded a new version of MonticelloConfigurations to project The Trunk: http://source.squeak.org/trunk/MonticelloConfigurations-dtl.135.mcz ==================== Summary ==================== Name: MonticelloConfigurations-dtl.135 Author: dtl Time: 30 May 2015, 8:10:12.525 am UUID: aabac991-61d2-4a2f-82e9-39e8572e2099 Ancestors: MonticelloConfigurations-eem.134 Restore missing method required by SqueakTrunk CI job =============== Diff against MonticelloConfigurations-eem.134 =============== Item was added: + ----- Method: MCMcmUpdater class>>updateFromDefaultRepository (in category 'updating') ----- + updateFromDefaultRepository + "Update from the default repository only" + + ^ self default updateFromDefaultRepository + ! From asqueaker at gmail.com Sat May 30 16:35:37 2015 From: asqueaker at gmail.com (Chris Muller) Date: Sat May 30 16:35:44 2015 Subject: [squeak-dev] The Trunk: System-eem.740.mcz In-Reply-To: References: <5568f1e7.76578c0a.229b.1440SMTPIN_ADDED_MISSING@mx.google.com> Message-ID: I've always considered two different ways to deliver changes and sources, and never got enough experience with it to know which I preferred. The first approach was for the changes file to contain the changes that occurred from the prior release to arrive at the current release. The second way was that the changes file would start empty at the beginning of the release, and then any changes the user put in are in that file, which seems to makes sense. Since we can keep all prior history in sources now, seems like the second approach is best. 4.6 deserves a new sources file, and #prepareNewRelease is where we should do whatever we're gonna do, every release. #condenseSources (historically) seems like the right thing to do for every release, so how about that? But can condenseSources be run non-interactively? On Fri, May 29, 2015 at 7:17 PM, Eliot Miranda wrote: > Hi Chris, > > On Fri, May 29, 2015 at 4:27 PM, Chris Muller wrote: >> >> Thanks Eliot these features are needed for the release. > > > So what about the details? here's a straw man. Produce Squeak 4.6's > changes file by doing condenseChanges on an updated image, but still keeping > SqueakV41.sources as its source file. Produce Squeak 5.0's sources file by > doing condenseSources on an undated Spur image, which will result in an > empty changes file. > >> >> >> On Fri, May 29, 2015 at 6:10 PM, wrote: >> > Eliot Miranda uploaded a new version of System to project The Trunk: >> > http://source.squeak.org/trunk/System-eem.740.mcz >> > >> > ==================== Summary ==================== >> > >> > Name: System-eem.740 >> > Author: eem >> > Time: 29 May 2015, 4:09:46.189 pm >> > UUID: 53894fe9-e3f5-44c7-b4c2-101e4d72f0d3 >> > Ancestors: System-eem.739 >> > >> > Modify condensSources to preserve direct method history. >> > >> > =============== Diff against System-eem.739 =============== >> > >> > Item was changed: >> > ----- Method: SmalltalkImage>>condenseSources (in category >> > 'housekeeping') ----- >> > condenseSources >> > "Move all the changes onto a compacted sources file." >> > "Smalltalk condenseSources" >> > >> > | newSourcesFile defaultDirectory newVersion currentVersion | >> > Utilities fixUpProblemsWithAllCategory. >> > "The above removes any concrete, spurious '-- all --' >> > categories, which mess up the process." >> > defaultDirectory := FileDirectory default. >> > currentVersion := self sourceFileVersionString. >> > newVersion := UIManager default >> > request: 'Please designate the version\for the new >> > source code file...' withCRs >> > initialAnswer: currentVersion. >> > newVersion ifEmpty: [ ^ self ]. >> > newVersion = currentVersion ifTrue: [ ^ self error: 'The new >> > source file must not be the same as the old.' ]. >> > self sourceFileVersionString: newVersion. >> > >> > "Write all sources with fileIndex 1" >> > newSourcesFile := defaultDirectory newFileNamed: >> > (defaultDirectory localNameFor: self sourcesName). >> > newSourcesFile ifNil: [ ^ self error: 'Couldn''t create source >> > code file in\' withCRs, defaultDirectory name]. >> > newSourcesFile >> > header; >> > timeStamp. >> > 'Condensing Sources File...' >> > displayProgressFrom: 0 >> > to: self classNames size + self traitNames size >> > during: >> > [ :bar | >> > | count | >> > count := 0. >> > Smalltalk allClassesAndTraitsDo: >> > [ :classOrTrait | >> > bar value: (count := count + 1). >> > classOrTrait >> > fileOutOn: newSourcesFile >> > + moveSource: #historically >> > - moveSource: true >> > toFile: 1 ] ]. >> > newSourcesFile >> > trailer; >> > close. >> > >> > "Make a new empty changes file" >> > self closeSourceFiles. >> > defaultDirectory >> > rename: self changesName >> > toBe: self changesName , '.old'. >> > (FileStream newFileNamed: self changesName) >> > header; >> > timeStamp; >> > close. >> > self lastQuitLogPosition: 0. >> > self setMacFileInfoOn: self changesName. >> > self setMacFileInfoOn: newSourcesFile name. >> > self openSourceFiles. >> > self inform: 'Source files have been rewritten to\' withCRs, >> > newSourcesFile name, '\Check that all is well,\and then save/quit.' withCRs! >> > >> > >> > > > > -- > best, > Eliot > > > From commits at source.squeak.org Sat May 30 21:55:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 30 21:55:08 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150530215507.6140.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008713.html Name: Compiler-eem.299 Ancestors: Compiler-eem.298 Provide support for a specialized pushNClosureTemps: bytecode, as included in the Sista bytecode set. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008714.html Name: Compiler-eem.300 Ancestors: Compiler-eem.299 Use the size/emitPushNClosureTemps: api in block generation. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008715.html Name: ReleaseBuilder-cmm.123 Ancestors: ReleaseBuilder-topa.122 - #clearPasswords was renamed to #clearCredentials. - Updated ReleaseBuilder class>>#versionString. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008716.html Name: Collections-eem.636 Ancestors: Collections-mt.635 findLast:startingAt: dual for findFirst:startingAt: ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008717.html Name: Kernel-eem.927 Ancestors: Kernel-eem.926 Support for condensing sources and changes while preserving direct history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008718.html Name: System-eem.739 Ancestors: System-cmm.738 Support for condensing sources and changes while preserving direct history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008719.html Name: Kernel-eem.928 Ancestors: Kernel-eem.927 Modify condenseChanges to preserve direct method history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008720.html Name: System-eem.740 Ancestors: System-eem.739 Modify condensSources to preserve direct method history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008721.html Name: Collections.spur-eem.636 Ancestors: Collections-eem.636, Collections.spur-mt.635 Collections-eem.636 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 findLast:startingAt: dual for findFirst:startingAt: ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008722.html Name: Compiler.spur-eem.298 Ancestors: Compiler-eem.298, Compiler.spur-cmm.297 Compiler-eem.298 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Provide multiple-bytecode-sets aware support for markerOrNil ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008723.html Name: Compiler.spur-eem.299 Ancestors: Compiler-eem.299, Compiler.spur-eem.298 Compiler-eem.299 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Provide support for a specialized pushNClosureTemps: bytecode, as included in the Sista bytecode set. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008724.html Name: Compiler.spur-eem.300 Ancestors: Compiler-eem.300, Compiler.spur-eem.299 Compiler-eem.300 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Use the size/emitPushNClosureTemps: api in block generation. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008725.html Name: Kernel.spur-cmm.925 Ancestors: Kernel-cmm.925, Kernel.spur-mt.924 Kernel-cmm.925 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Fix an error in an error-handler. Any Exception can and must be able to #printVerboseOn:, not just Errors. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008726.html Name: Kernel.spur-eem.926 Ancestors: Kernel-eem.926, Kernel.spur-cmm.925 Kernel-eem.926 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Make markerOrNil multiple-bytecode-sets aware ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008727.html Name: Kernel.spur-eem.927 Ancestors: Kernel-eem.927, Kernel.spur-eem.926 Kernel-eem.927 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Support for condensing sources and changes while preserving direct history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008728.html Name: Kernel.spur-eem.928 Ancestors: Kernel-eem.928, Kernel.spur-eem.927 Kernel-eem.928 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Modify condenseChanges to preserve direct method history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008729.html Name: System.spur-cmm.738 Ancestors: System-cmm.738, System.spur-ul.737 System-cmm.738 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Fix #run: leaving headless image stuck because there was a MNU or Halt. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008730.html Name: System.spur-eem.739 Ancestors: System-eem.739, System.spur-cmm.738 System-eem.739 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Support for condensing sources and changes while preserving direct history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008731.html Name: System.spur-eem.740 Ancestors: System-eem.740, System.spur-eem.739 System-eem.740 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Modify condensSources to preserve direct method history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008732.html Name: Kernel.spur-cmm.925 Ancestors: Kernel-cmm.925, Kernel.spur-mt.924 Kernel-cmm.925 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.268 Fix an error in an error-handler. Any Exception can and must be able to #printVerboseOn:, not just Errors. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008733.html Name: Kernel.spur-eem.926 Ancestors: Kernel-eem.926, Kernel.spur-cmm.925 Kernel-eem.926 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.268 Make markerOrNil multiple-bytecode-sets aware ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008734.html Name: Kernel.spur-eem.927 Ancestors: Kernel-eem.927, Kernel.spur-eem.926 Kernel-eem.927 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.268 Support for condensing sources and changes while preserving direct history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008735.html Name: Kernel.spur-eem.928 Ancestors: Kernel-eem.928, Kernel.spur-eem.927 Kernel-eem.928 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.267 Modify condenseChanges to preserve direct method history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008736.html Name: Kernel.spur-eem.928 Ancestors: Kernel-eem.928, Kernel.spur-eem.927 Kernel-eem.928 patched for Spur by SpurBootstrapMonticelloPackagePatcher Cog-eem.268 Modify condenseChanges to preserve direct method history. ============================================= http://lists.squeakfoundation.org/pipermail/packages/2015-May/008737.html Name: MonticelloConfigurations-dtl.135 Ancestors: MonticelloConfigurations-eem.134 Restore missing method required by SqueakTrunk CI job ============================================= From commits at source.squeak.org Sat May 30 22:14:11 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sat May 30 22:14:17 2015 Subject: [squeak-dev] The Trunk: 46Deprecated-dtl.4.mcz Message-ID: David T. Lewis uploaded a new version of 46Deprecated to project The Trunk: http://source.squeak.org/trunk/46Deprecated-dtl.4.mcz ==================== Summary ==================== Name: 46Deprecated-dtl.4 Author: dtl Time: 30 May 2015, 6:14:05.154 pm UUID: 69e9c6e3-c82e-445b-b82d-adc42cacb06b Ancestors: 46Deprecated-mt.3 Provide an implementation of MCMcmUpdater class>>useLatestPackagesFrom: because an older image may be referencing it while trying to update itself from a block in the earler class side implementation, in which case we should delegate to the current default instance of MCMcmUpdater. =============== Diff against 46Deprecated-mt.3 =============== Item was added: + ----- Method: MCMcmUpdater class>>useLatestPackagesFrom: (in category '*46Deprecated') ----- + useLatestPackagesFrom: repo + "For overriding on a per repository basis. + Implementation is now on the instance side, but is also maintained here because + an older image may be trying to update to current and may still be evaluating a block + in its class:>>updateFromRepositoriesMCMcmUpdater that expects thiis method to + be present. Delegate to the current default instance." + + ^ self default useLatestPackagesFrom: repo + ! From lewis at mail.msen.com Sat May 30 22:52:30 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat May 30 22:52:34 2015 Subject: [squeak-dev] MCMUpdater and CI In-Reply-To: <03D231FC-84D8-4F13-B684-368C4C5C060C@gmx.de> References: <03D231FC-84D8-4F13-B684-368C4C5C060C@gmx.de> Message-ID: <20150530225230.GA54129@shell.msen.com> On Fri, May 29, 2015 at 09:25:58PM +0200, Tobias Pape wrote: > Hey > > We have changed the way the MCMUpdater works, I recall. > Probably this has broken the CI Build: > http://build.squeak.org/job/SqueakTrunk/1493/console > > Who can take a look at it? > It's partly fixed, but not quite. The SqueakTrunk CI uses MCMcmUpdater class>>updateFromDefaultRepository, so I restored an implementation (delegating to MCMcmUpdater current) in MonticelloConfigurations-dtl.135. With that in place, the update from Squeak4.5 to current trunk fails because the old image is evaluating a block that expects MCMcmUpdater class>>useLatestPackagesFrom: so I added that back to the class side of MCMcmUpdater in 46Deprecated-dtl.4. I think I still need to fix the update maps to load the missing method, and then it will probably work. I will edit update-eem.315.mcm and have it load 46Deprecated-dtl.4 instead of 46Deprecated-mt.3. If this works, update.spur-eem.mcm will need the same change. Dave From lewis at mail.msen.com Sat May 30 23:32:57 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sat May 30 23:33:01 2015 Subject: [squeak-dev] MCMUpdater and CI In-Reply-To: <20150530225230.GA54129@shell.msen.com> References: <03D231FC-84D8-4F13-B684-368C4C5C060C@gmx.de> <20150530225230.GA54129@shell.msen.com> Message-ID: <20150530233257.GA71380@shell.msen.com> On Sat, May 30, 2015 at 06:52:30PM -0400, David T. Lewis wrote: > On Fri, May 29, 2015 at 09:25:58PM +0200, Tobias Pape wrote: > > Hey > > > > We have changed the way the MCMUpdater works, I recall. > > Probably this has broken the CI Build: > > http://build.squeak.org/job/SqueakTrunk/1493/console > > > > Who can take a look at it? > > > > It's partly fixed, but not quite. > > The SqueakTrunk CI uses MCMcmUpdater class>>updateFromDefaultRepository, > so I restored an implementation (delegating to MCMcmUpdater current) in > MonticelloConfigurations-dtl.135. > > With that in place, the update from Squeak4.5 to current trunk fails because the > old image is evaluating a block that expects MCMcmUpdater class>>useLatestPackagesFrom: > so I added that back to the class side of MCMcmUpdater in 46Deprecated-dtl.4. > > I think I still need to fix the update maps to load the missing method, and > then it will probably work. > > I will edit update-eem.315.mcm and have it load 46Deprecated-dtl.4 instead of > 46Deprecated-mt.3. If this works, update.spur-eem.mcm will need the same change. I edited and saved both update-eem.315.mcm and update.spur-eem.mcm so that they both require 46Deprecated-dtl.4. This seems like a bad thing do do, since I am modifying an mcm with someone else's author initials, but it did seem to work, and the SqueakTrunk CI job is no longer failing. Dave From Das.Linux at gmx.de Sun May 31 09:47:12 2015 From: Das.Linux at gmx.de (Tobias Pape) Date: Sun May 31 09:47:17 2015 Subject: [squeak-dev] MCMUpdater and CI In-Reply-To: <20150530233257.GA71380@shell.msen.com> References: <03D231FC-84D8-4F13-B684-368C4C5C060C@gmx.de> <20150530225230.GA54129@shell.msen.com> <20150530233257.GA71380@shell.msen.com> Message-ID: <6477976F-35CA-45DA-9EAD-7626D005CE8C@gmx.de> On 31.05.2015, at 01:32, David T. Lewis wrote: > On Sat, May 30, 2015 at 06:52:30PM -0400, David T. Lewis wrote: >> On Fri, May 29, 2015 at 09:25:58PM +0200, Tobias Pape wrote: >>> Hey >>> >>> We have changed the way the MCMUpdater works, I recall. >>> Probably this has broken the CI Build: >>> http://build.squeak.org/job/SqueakTrunk/1493/console >>> >>> Who can take a look at it? >>> >> >> It's partly fixed, but not quite. >> >> The SqueakTrunk CI uses MCMcmUpdater class>>updateFromDefaultRepository, >> so I restored an implementation (delegating to MCMcmUpdater current) in >> MonticelloConfigurations-dtl.135. >> >> With that in place, the update from Squeak4.5 to current trunk fails because the >> old image is evaluating a block that expects MCMcmUpdater class>>useLatestPackagesFrom: >> so I added that back to the class side of MCMcmUpdater in 46Deprecated-dtl.4. >> >> I think I still need to fix the update maps to load the missing method, and >> then it will probably work. >> >> I will edit update-eem.315.mcm and have it load 46Deprecated-dtl.4 instead of >> 46Deprecated-mt.3. If this works, update.spur-eem.mcm will need the same change. > > I edited and saved both update-eem.315.mcm and update.spur-eem.mcm so that they > both require 46Deprecated-dtl.4. This seems like a bad thing do do, since I am > modifying an mcm with someone else's author initials, but it did seem to work, > and the SqueakTrunk CI job is no longer failing. Yay! Thank you :) Best regards -Tobias From trygver at ifi.uio.no Sun May 31 14:52:45 2015 From: trygver at ifi.uio.no (Trygve Reenskaug) Date: Sun May 31 14:52:52 2015 Subject: [squeak-dev] Mac Squeak binary virtual machine for Squeak 3.10.2 Message-ID: <556B203D.60906@ifi.uio.no> Hi, A friend of mine is doing some experiments using a Mac and my program Baby IDE. BabyIDE is works under Squeak 3.10.2. Is there a binary virtual machine for a current Mac that he can use? Please answer to /trygver@ifi.uio.no/ since I no longer follow the mailing list. Thank you --Trygve -- /The essence of object orientation is that objects collaborateto achieve a goal. / Trygve Reenskaug mailto: trygver@ifi.uio.no Morgedalsvn. 5A http://folk.uio.no/trygver/ N-0378 Oslo http://fullOO.info Norway Tel: (+47) 22 49 57 27 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20150531/64dc69dd/attachment-0001.htm From lewis at mail.msen.com Sun May 31 15:45:22 2015 From: lewis at mail.msen.com (David T. Lewis) Date: Sun May 31 15:45:29 2015 Subject: [squeak-dev] Mac Squeak binary virtual machine for Squeak 3.10.2 In-Reply-To: <556B203D.60906@ifi.uio.no> References: <556B203D.60906@ifi.uio.no> Message-ID: <20150531154522.GA16900@shell.msen.com> On Sun, May 31, 2015 at 04:52:45PM +0200, Trygve Reenskaug wrote: > Hi, > A friend of mine is doing some experiments using a Mac and my program > Baby IDE. BabyIDE is works under Squeak 3.10.2. Is there a binary > virtual machine for a current Mac that he can use? > > Please answer to /trygver@ifi.uio.no/ since I no longer follow the > mailing list. > > Thank you > --Trygve > Hello Trygve, Please try the VM here and see if it works for you: http://squeakvm.org/~lewis/MacOS-test-Javier/ Javier Diaz-Reinoso provided this last November. It is an up to date interpreter VM that should be suitable for running Squeak 3.10.2 (and also for the latest Squeak 4.5 or 4.6 images). John McIntosh is also in the process of updating the Mac VMs, so there may soon be a newer update: http://lists.squeakfoundation.org/pipermail/vm-dev/2015-May/018554.html But for now I think the VM from Javier should do what you need. Hope this helps, Dave From commits at source.squeak.org Sun May 31 21:55:07 2015 From: commits at source.squeak.org (commits@source.squeak.org) Date: Sun May 31 21:55:08 2015 Subject: [squeak-dev] Daily Commit Log Message-ID: <20150531215507.20184.qmail@box4.squeakfoundation.org> Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours: http://lists.squeakfoundation.org/pipermail/packages/2015-May/008738.html Name: 46Deprecated-dtl.4 Ancestors: 46Deprecated-mt.3 Provide an implementation of MCMcmUpdater class>>useLatestPackagesFrom: because an older image may be referencing it while trying to update itself from a block in the earler class side implementation, in which case we should delegate to the current default instance of MCMcmUpdater. =============================================